--- a/Admin/mirror-website Mon May 11 09:39:53 2009 +0200
+++ b/Admin/mirror-website Mon May 11 17:20:52 2009 +0200
@@ -12,7 +12,7 @@
;;
*.cl.cam.ac.uk)
USER=paulson
- DEST=/anfs/www/html/Research/HVG/Isabelle
+ DEST=/anfs/www/html/research/hvg/Isabelle
;;
*)
echo "Unknown destination directory for ${HOST}"
--- a/CONTRIBUTORS Mon May 11 09:39:53 2009 +0200
+++ b/CONTRIBUTORS Mon May 11 17:20:52 2009 +0200
@@ -7,6 +7,10 @@
Contributions to this Isabelle version
--------------------------------------
+
+Contributions to Isabelle2009
+-----------------------------
+
* March 2009: Robert Himmelmann, TUM and Amine Chaieb, University of
Cambridge
Elementary topology in Euclidean space.
--- a/NEWS Mon May 11 09:39:53 2009 +0200
+++ b/NEWS Mon May 11 17:20:52 2009 +0200
@@ -4,6 +4,26 @@
New in this Isabelle version
----------------------------
+*** Pure ***
+
+* On instantiation of classes, remaining undefined class parameters are
+formally declared. INCOMPATIBILITY.
+
+
+*** HOL ***
+
+* Class semiring_div requires superclass no_zero_divisors and proof of div_mult_mult1;
+theorems div_mult_mult1, div_mult_mult2, div_mult_mult1_if, div_mult_mult1 and
+div_mult_mult2 have been generalized to class semiring_div, subsuming former
+theorems zdiv_zmult_zmult1, zdiv_zmult_zmult1_if, zdiv_zmult_zmult1 and zdiv_zmult_zmult2.
+div_mult_mult1 is now [simp] by default. INCOMPATIBILITY.
+
+* Power operations on relations and functions are now one dedicate constant compow with
+infix syntax "^^". Power operations on multiplicative monoids retains syntax "^"
+and is now defined generic in class power. INCOMPATIBILITY.
+
+* ML antiquotation @{code_datatype} inserts definition of a datatype generated
+by the code generator; see Predicate.thy for an example.
New in Isabelle2009 (April 2009)
@@ -187,7 +207,7 @@
* Keyword 'code_exception' now named 'code_abort'. INCOMPATIBILITY.
-* Unified theorem tables for both code code generators. Thus [code
+* Unified theorem tables for both code generators. Thus [code
func] has disappeared and only [code] remains. INCOMPATIBILITY.
* Command 'find_consts' searches for constants based on type and name
--- a/contrib/SystemOnTPTP/remote Mon May 11 09:39:53 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-#!/usr/bin/env perl
-#
-# Wrapper for custom remote provers on SystemOnTPTP
-# Author: Fabian Immler, TU Muenchen
-#
-
-use warnings;
-use strict;
-use Getopt::Std;
-use HTTP::Request::Common;
-use LWP;
-
-my $SystemOnTPTPFormReplyURL = "http://www.cs.miami.edu/~tptp/cgi-bin/SystemOnTPTPFormReply";
-
-# default parameters
-my %URLParameters = (
- "NoHTML" => 1,
- "QuietFlag" => "-q01",
- "X2TPTP" => "-S",
- "SubmitButton" => "RunSelectedSystems",
- "ProblemSource" => "UPLOAD",
- );
-
-#----Get format and transform options if specified
-my %Options;
-getopts("hws:t:c:",\%Options);
-
-#----Usage
-sub usage() {
- print("Usage: remote [<options>] <File name>\n");
- print(" <options> are ...\n");
- print(" -h - print this help\n");
- print(" -w - list available ATP systems\n");
- print(" -s<system> - specified system to use\n");
- print(" -t<timelimit> - CPU time limit for system\n");
- print(" -c<command> - custom command for system\n");
- print(" <File name> - TPTP problem file\n");
- exit(0);
-}
-if (exists($Options{'h'})) {
- usage();
-}
-#----What systems flag
-if (exists($Options{'w'})) {
- $URLParameters{"SubmitButton"} = "ListSystems";
- delete($URLParameters{"ProblemSource"});
-}
-#----Selected system
-my $System;
-if (exists($Options{'s'})) {
- $System = $Options{'s'};
-} else {
- # use Vampire as default
- $System = "Vampire---9.0";
-}
-$URLParameters{"System___$System"} = $System;
-
-#----Time limit
-if (exists($Options{'t'})) {
- $URLParameters{"TimeLimit___$System"} = $Options{'t'};
-}
-#----Custom command
-if (exists($Options{'c'})) {
- $URLParameters{"Command___$System"} = $Options{'c'};
-}
-
-#----Get single file name
-if (exists($URLParameters{"ProblemSource"})) {
- if (scalar(@ARGV) >= 1) {
- $URLParameters{"UPLOADProblem"} = [shift(@ARGV)];
- } else {
- print("Missing problem file\n");
- usage();
- die;
- }
-}
-
-# Query Server
-my $Agent = LWP::UserAgent->new;
-if (exists($Options{'t'})) {
- # give server more time to respond
- $Agent->timeout($Options{'t'} + 10);
-}
-my $Request = POST($SystemOnTPTPFormReplyURL,
- Content_Type => 'form-data',Content => \%URLParameters);
-my $Response = $Agent->request($Request);
-
-#catch errors / failure
-if(! $Response->is_success){
- print "HTTP-Error: " . $Response->message . "\n";
- exit(-1);
-} elsif (exists($Options{'w'})) {
- print $Response->content;
- exit (0);
-} elsif ($Response->content =~ /WARNING: (\S*) does not exist/) {
- print "Specified System $1 does not exist\n";
- exit(-1);
-} elsif ($Response->content =~ /%\s*Result\s*:\s*Unsatisfiable.*\n%\s*Output\s*:\s*(CNF)?Refutation.*\n%/) {
- my @lines = split( /\n/, $Response->content);
- my $extract = "";
- foreach my $line (@lines){
- #ignore comments
- if ($line !~ /^%/ && !($line eq "")) {
- $extract .= "$line";
- }
- }
- # insert newlines after ').'
- $extract =~ s/\s//g;
- $extract =~ s/\)\.cnf/\)\.\ncnf/g;
-
- # orientation for res_reconstruct.ML
- print "# SZS output start CNFRefutation.\n";
- print "$extract\n";
- print "# SZS output end CNFRefutation.\n";
- exit(0);
-} else {
- print "Remote-script could not extract proof:\n".$Response->content;
- exit(-1);
-}
-
--- a/doc-src/Codegen/Makefile Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Codegen/Makefile Mon May 11 17:20:52 2009 +0200
@@ -17,7 +17,7 @@
dvi: $(NAME).dvi
-$(NAME).dvi: $(FILES) isabelle_isar.eps architecture.eps adaption.eps
+$(NAME).dvi: $(FILES) isabelle_isar.eps architecture.eps adaptation.eps
$(LATEX) $(NAME)
$(BIBTEX) $(NAME)
$(LATEX) $(NAME)
@@ -25,7 +25,7 @@
pdf: $(NAME).pdf
-$(NAME).pdf: $(FILES) isabelle_isar.pdf architecture.pdf adaption.pdf
+$(NAME).pdf: $(FILES) isabelle_isar.pdf architecture.pdf adaptation.pdf
$(PDFLATEX) $(NAME)
$(BIBTEX) $(NAME)
$(PDFLATEX) $(NAME)
@@ -37,17 +37,17 @@
architecture.dvi: Thy/pictures/architecture.tex
latex -output-directory=$(dir $@) $<
-adaption.dvi: Thy/pictures/adaption.tex
+adaptation.dvi: Thy/pictures/adaptation.tex
latex -output-directory=$(dir $@) $<
architecture.eps: architecture.dvi
dvips -E -o $@ $<
-adaption.eps: adaption.dvi
+adaptation.eps: adaptation.dvi
dvips -E -o $@ $<
architecture.pdf: architecture.eps
epstopdf --outfile=$@ $<
-adaption.pdf: adaption.eps
+adaptation.pdf: adaptation.eps
epstopdf --outfile=$@ $<
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc-src/Codegen/Thy/Adaptation.thy Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,326 @@
+theory Adaptation
+imports Setup
+begin
+
+setup %invisible {* Code_Target.extend_target ("\<SML>", ("SML", K I)) *}
+
+section {* Adaptation to target languages \label{sec:adaptation} *}
+
+subsection {* Adapting code generation *}
+
+text {*
+ The aspects of code generation introduced so far have two aspects
+ in common:
+
+ \begin{itemize}
+ \item They act uniformly, without reference to a specific
+ target language.
+ \item They are \emph{safe} in the sense that as long as you trust
+ the code generator meta theory and implementation, you cannot
+ produce programs that yield results which are not derivable
+ in the logic.
+ \end{itemize}
+
+ \noindent In this section we will introduce means to \emph{adapt} the serialiser
+ to a specific target language, i.e.~to print program fragments
+ in a way which accommodates \qt{already existing} ingredients of
+ a target language environment, for three reasons:
+
+ \begin{itemize}
+ \item improving readability and aesthetics of generated code
+ \item gaining efficiency
+ \item interface with language parts which have no direct counterpart
+ in @{text "HOL"} (say, imperative data structures)
+ \end{itemize}
+
+ \noindent Generally, you should avoid using those features yourself
+ \emph{at any cost}:
+
+ \begin{itemize}
+ \item The safe configuration methods act uniformly on every target language,
+ whereas for adaptation you have to treat each target language separate.
+ \item Application is extremely tedious since there is no abstraction
+ which would allow for a static check, making it easy to produce garbage.
+ \item More or less subtle errors can be introduced unconsciously.
+ \end{itemize}
+
+ \noindent However, even if you ought refrain from setting up adaptation
+ yourself, already the @{text "HOL"} comes with some reasonable default
+ adaptations (say, using target language list syntax). There also some
+ common adaptation cases which you can setup by importing particular
+ library theories. In order to understand these, we provide some clues here;
+ these however are not supposed to replace a careful study of the sources.
+*}
+
+subsection {* The adaptation principle *}
+
+text {*
+ Figure \ref{fig:adaptation} illustrates what \qt{adaptation} is conceptually
+ supposed to be:
+
+ \begin{figure}[here]
+ \includegraphics{adaptation}
+ \caption{The adaptation principle}
+ \label{fig:adaptation}
+ \end{figure}
+
+ \noindent In the tame view, code generation acts as broker between
+ @{text logic}, @{text "intermediate language"} and
+ @{text "target language"} by means of @{text translation} and
+ @{text serialisation}; for the latter, the serialiser has to observe
+ the structure of the @{text language} itself plus some @{text reserved}
+ keywords which have to be avoided for generated code.
+ However, if you consider @{text adaptation} mechanisms, the code generated
+ by the serializer is just the tip of the iceberg:
+
+ \begin{itemize}
+ \item @{text serialisation} can be \emph{parametrised} such that
+ logical entities are mapped to target-specific ones
+ (e.g. target-specific list syntax,
+ see also \secref{sec:adaptation_mechanisms})
+ \item Such parametrisations can involve references to a
+ target-specific standard @{text library} (e.g. using
+ the @{text Haskell} @{verbatim Maybe} type instead
+ of the @{text HOL} @{type "option"} type);
+ if such are used, the corresponding identifiers
+ (in our example, @{verbatim Maybe}, @{verbatim Nothing}
+ and @{verbatim Just}) also have to be considered @{text reserved}.
+ \item Even more, the user can enrich the library of the
+ target-language by providing code snippets
+ (\qt{@{text "includes"}}) which are prepended to
+ any generated code (see \secref{sec:include}); this typically
+ also involves further @{text reserved} identifiers.
+ \end{itemize}
+
+ \noindent As figure \ref{fig:adaptation} illustrates, all these adaptation mechanisms
+ have to act consistently; it is at the discretion of the user
+ to take care for this.
+*}
+
+subsection {* Common adaptation patterns *}
+
+text {*
+ The @{theory HOL} @{theory Main} theory already provides a code
+ generator setup
+ which should be suitable for most applications. Common extensions
+ and modifications are available by certain theories of the @{text HOL}
+ library; beside being useful in applications, they may serve
+ as a tutorial for customising the code generator setup (see below
+ \secref{sec:adaptation_mechanisms}).
+
+ \begin{description}
+
+ \item[@{theory "Code_Integer"}] represents @{text HOL} integers by big
+ integer literals in target languages.
+ \item[@{theory "Code_Char"}] represents @{text HOL} characters by
+ character literals in target languages.
+ \item[@{theory "Code_Char_chr"}] like @{text "Code_Char"},
+ but also offers treatment of character codes; includes
+ @{theory "Code_Char"}.
+ \item[@{theory "Efficient_Nat"}] \label{eff_nat} implements natural numbers by integers,
+ which in general will result in higher efficiency; pattern
+ matching with @{term "0\<Colon>nat"} / @{const "Suc"}
+ is eliminated; includes @{theory "Code_Integer"}
+ and @{theory "Code_Index"}.
+ \item[@{theory "Code_Index"}] provides an additional datatype
+ @{typ index} which is mapped to target-language built-in integers.
+ Useful for code setups which involve e.g. indexing of
+ target-language arrays.
+ \item[@{theory "String"}] provides an additional datatype
+ @{typ message_string} which is isomorphic to strings;
+ @{typ message_string}s are mapped to target-language strings.
+ Useful for code setups which involve e.g. printing (error) messages.
+
+ \end{description}
+
+ \begin{warn}
+ When importing any of these theories, they should form the last
+ items in an import list. Since these theories adapt the
+ code generator setup in a non-conservative fashion,
+ strange effects may occur otherwise.
+ \end{warn}
+*}
+
+
+subsection {* Parametrising serialisation \label{sec:adaptation_mechanisms} *}
+
+text {*
+ Consider the following function and its corresponding
+ SML code:
+*}
+
+primrec %quote in_interval :: "nat \<times> nat \<Rightarrow> nat \<Rightarrow> bool" where
+ "in_interval (k, l) n \<longleftrightarrow> k \<le> n \<and> n \<le> l"
+(*<*)
+code_type %invisible bool
+ (SML)
+code_const %invisible True and False and "op \<and>" and Not
+ (SML and and and)
+(*>*)
+text %quote {*@{code_stmts in_interval (SML)}*}
+
+text {*
+ \noindent Though this is correct code, it is a little bit unsatisfactory:
+ boolean values and operators are materialised as distinguished
+ entities with have nothing to do with the SML-built-in notion
+ of \qt{bool}. This results in less readable code;
+ additionally, eager evaluation may cause programs to
+ loop or break which would perfectly terminate when
+ the existing SML @{verbatim "bool"} would be used. To map
+ the HOL @{typ bool} on SML @{verbatim "bool"}, we may use
+ \qn{custom serialisations}:
+*}
+
+code_type %quotett bool
+ (SML "bool")
+code_const %quotett True and False and "op \<and>"
+ (SML "true" and "false" and "_ andalso _")
+
+text {*
+ \noindent The @{command code_type} command takes a type constructor
+ as arguments together with a list of custom serialisations.
+ Each custom serialisation starts with a target language
+ identifier followed by an expression, which during
+ code serialisation is inserted whenever the type constructor
+ would occur. For constants, @{command code_const} implements
+ the corresponding mechanism. Each ``@{verbatim "_"}'' in
+ a serialisation expression is treated as a placeholder
+ for the type constructor's (the constant's) arguments.
+*}
+
+text %quote {*@{code_stmts in_interval (SML)}*}
+
+text {*
+ \noindent This still is not perfect: the parentheses
+ around the \qt{andalso} expression are superfluous.
+ Though the serialiser
+ by no means attempts to imitate the rich Isabelle syntax
+ framework, it provides some common idioms, notably
+ associative infixes with precedences which may be used here:
+*}
+
+code_const %quotett "op \<and>"
+ (SML infixl 1 "andalso")
+
+text %quote {*@{code_stmts in_interval (SML)}*}
+
+text {*
+ \noindent The attentive reader may ask how we assert that no generated
+ code will accidentally overwrite. For this reason the serialiser has
+ an internal table of identifiers which have to be avoided to be used
+ for new declarations. Initially, this table typically contains the
+ keywords of the target language. It can be extended manually, thus avoiding
+ accidental overwrites, using the @{command "code_reserved"} command:
+*}
+
+code_reserved %quote "\<SML>" bool true false andalso
+
+text {*
+ \noindent Next, we try to map HOL pairs to SML pairs, using the
+ infix ``@{verbatim "*"}'' type constructor and parentheses:
+*}
+(*<*)
+code_type %invisible *
+ (SML)
+code_const %invisible Pair
+ (SML)
+(*>*)
+code_type %quotett *
+ (SML infix 2 "*")
+code_const %quotett Pair
+ (SML "!((_),/ (_))")
+
+text {*
+ \noindent The initial bang ``@{verbatim "!"}'' tells the serialiser
+ never to put
+ parentheses around the whole expression (they are already present),
+ while the parentheses around argument place holders
+ tell not to put parentheses around the arguments.
+ The slash ``@{verbatim "/"}'' (followed by arbitrary white space)
+ inserts a space which may be used as a break if necessary
+ during pretty printing.
+
+ These examples give a glimpse what mechanisms
+ custom serialisations provide; however their usage
+ requires careful thinking in order not to introduce
+ inconsistencies -- or, in other words:
+ custom serialisations are completely axiomatic.
+
+ A further noteworthy details is that any special
+ character in a custom serialisation may be quoted
+ using ``@{verbatim "'"}''; thus, in
+ ``@{verbatim "fn '_ => _"}'' the first
+ ``@{verbatim "_"}'' is a proper underscore while the
+ second ``@{verbatim "_"}'' is a placeholder.
+*}
+
+
+subsection {* @{text Haskell} serialisation *}
+
+text {*
+ For convenience, the default
+ @{text HOL} setup for @{text Haskell} maps the @{class eq} class to
+ its counterpart in @{text Haskell}, giving custom serialisations
+ for the class @{class eq} (by command @{command code_class}) and its operation
+ @{const HOL.eq}
+*}
+
+code_class %quotett eq
+ (Haskell "Eq")
+
+code_const %quotett "op ="
+ (Haskell infixl 4 "==")
+
+text {*
+ \noindent A problem now occurs whenever a type which
+ is an instance of @{class eq} in @{text HOL} is mapped
+ on a @{text Haskell}-built-in type which is also an instance
+ of @{text Haskell} @{text Eq}:
+*}
+
+typedecl %quote bar
+
+instantiation %quote bar :: eq
+begin
+
+definition %quote "eq_class.eq (x\<Colon>bar) y \<longleftrightarrow> x = y"
+
+instance %quote by default (simp add: eq_bar_def)
+
+end %quote (*<*)
+
+(*>*) code_type %quotett bar
+ (Haskell "Integer")
+
+text {*
+ \noindent The code generator would produce
+ an additional instance, which of course is rejected by the @{text Haskell}
+ compiler.
+ To suppress this additional instance, use
+ @{text "code_instance"}:
+*}
+
+code_instance %quotett bar :: eq
+ (Haskell -)
+
+
+subsection {* Enhancing the target language context \label{sec:include} *}
+
+text {*
+ In rare cases it is necessary to \emph{enrich} the context of a
+ target language; this is accomplished using the @{command "code_include"}
+ command:
+*}
+
+code_include %quotett Haskell "Errno"
+{*errno i = error ("Error number: " ++ show i)*}
+
+code_reserved %quotett Haskell Errno
+
+text {*
+ \noindent Such named @{text include}s are then prepended to every generated code.
+ Inspect such code in order to find out how @{command "code_include"} behaves
+ with respect to a particular target language.
+*}
+
+end
--- a/doc-src/Codegen/Thy/Adaption.thy Mon May 11 09:39:53 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,326 +0,0 @@
-theory Adaption
-imports Setup
-begin
-
-setup %invisible {* Code_Target.extend_target ("\<SML>", ("SML", K I)) *}
-
-section {* Adaption to target languages \label{sec:adaption} *}
-
-subsection {* Adapting code generation *}
-
-text {*
- The aspects of code generation introduced so far have two aspects
- in common:
-
- \begin{itemize}
- \item They act uniformly, without reference to a specific
- target language.
- \item They are \emph{safe} in the sense that as long as you trust
- the code generator meta theory and implementation, you cannot
- produce programs that yield results which are not derivable
- in the logic.
- \end{itemize}
-
- \noindent In this section we will introduce means to \emph{adapt} the serialiser
- to a specific target language, i.e.~to print program fragments
- in a way which accommodates \qt{already existing} ingredients of
- a target language environment, for three reasons:
-
- \begin{itemize}
- \item improving readability and aesthetics of generated code
- \item gaining efficiency
- \item interface with language parts which have no direct counterpart
- in @{text "HOL"} (say, imperative data structures)
- \end{itemize}
-
- \noindent Generally, you should avoid using those features yourself
- \emph{at any cost}:
-
- \begin{itemize}
- \item The safe configuration methods act uniformly on every target language,
- whereas for adaption you have to treat each target language separate.
- \item Application is extremely tedious since there is no abstraction
- which would allow for a static check, making it easy to produce garbage.
- \item More or less subtle errors can be introduced unconsciously.
- \end{itemize}
-
- \noindent However, even if you ought refrain from setting up adaption
- yourself, already the @{text "HOL"} comes with some reasonable default
- adaptions (say, using target language list syntax). There also some
- common adaption cases which you can setup by importing particular
- library theories. In order to understand these, we provide some clues here;
- these however are not supposed to replace a careful study of the sources.
-*}
-
-subsection {* The adaption principle *}
-
-text {*
- Figure \ref{fig:adaption} illustrates what \qt{adaption} is conceptually
- supposed to be:
-
- \begin{figure}[here]
- \includegraphics{adaption}
- \caption{The adaption principle}
- \label{fig:adaption}
- \end{figure}
-
- \noindent In the tame view, code generation acts as broker between
- @{text logic}, @{text "intermediate language"} and
- @{text "target language"} by means of @{text translation} and
- @{text serialisation}; for the latter, the serialiser has to observe
- the structure of the @{text language} itself plus some @{text reserved}
- keywords which have to be avoided for generated code.
- However, if you consider @{text adaption} mechanisms, the code generated
- by the serializer is just the tip of the iceberg:
-
- \begin{itemize}
- \item @{text serialisation} can be \emph{parametrised} such that
- logical entities are mapped to target-specific ones
- (e.g. target-specific list syntax,
- see also \secref{sec:adaption_mechanisms})
- \item Such parametrisations can involve references to a
- target-specific standard @{text library} (e.g. using
- the @{text Haskell} @{verbatim Maybe} type instead
- of the @{text HOL} @{type "option"} type);
- if such are used, the corresponding identifiers
- (in our example, @{verbatim Maybe}, @{verbatim Nothing}
- and @{verbatim Just}) also have to be considered @{text reserved}.
- \item Even more, the user can enrich the library of the
- target-language by providing code snippets
- (\qt{@{text "includes"}}) which are prepended to
- any generated code (see \secref{sec:include}); this typically
- also involves further @{text reserved} identifiers.
- \end{itemize}
-
- \noindent As figure \ref{fig:adaption} illustrates, all these adaption mechanisms
- have to act consistently; it is at the discretion of the user
- to take care for this.
-*}
-
-subsection {* Common adaption patterns *}
-
-text {*
- The @{theory HOL} @{theory Main} theory already provides a code
- generator setup
- which should be suitable for most applications. Common extensions
- and modifications are available by certain theories of the @{text HOL}
- library; beside being useful in applications, they may serve
- as a tutorial for customising the code generator setup (see below
- \secref{sec:adaption_mechanisms}).
-
- \begin{description}
-
- \item[@{theory "Code_Integer"}] represents @{text HOL} integers by big
- integer literals in target languages.
- \item[@{theory "Code_Char"}] represents @{text HOL} characters by
- character literals in target languages.
- \item[@{theory "Code_Char_chr"}] like @{text "Code_Char"},
- but also offers treatment of character codes; includes
- @{theory "Code_Char"}.
- \item[@{theory "Efficient_Nat"}] \label{eff_nat} implements natural numbers by integers,
- which in general will result in higher efficiency; pattern
- matching with @{term "0\<Colon>nat"} / @{const "Suc"}
- is eliminated; includes @{theory "Code_Integer"}
- and @{theory "Code_Index"}.
- \item[@{theory "Code_Index"}] provides an additional datatype
- @{typ index} which is mapped to target-language built-in integers.
- Useful for code setups which involve e.g. indexing of
- target-language arrays.
- \item[@{theory "Code_Message"}] provides an additional datatype
- @{typ message_string} which is isomorphic to strings;
- @{typ message_string}s are mapped to target-language strings.
- Useful for code setups which involve e.g. printing (error) messages.
-
- \end{description}
-
- \begin{warn}
- When importing any of these theories, they should form the last
- items in an import list. Since these theories adapt the
- code generator setup in a non-conservative fashion,
- strange effects may occur otherwise.
- \end{warn}
-*}
-
-
-subsection {* Parametrising serialisation \label{sec:adaption_mechanisms} *}
-
-text {*
- Consider the following function and its corresponding
- SML code:
-*}
-
-primrec %quote in_interval :: "nat \<times> nat \<Rightarrow> nat \<Rightarrow> bool" where
- "in_interval (k, l) n \<longleftrightarrow> k \<le> n \<and> n \<le> l"
-(*<*)
-code_type %invisible bool
- (SML)
-code_const %invisible True and False and "op \<and>" and Not
- (SML and and and)
-(*>*)
-text %quote {*@{code_stmts in_interval (SML)}*}
-
-text {*
- \noindent Though this is correct code, it is a little bit unsatisfactory:
- boolean values and operators are materialised as distinguished
- entities with have nothing to do with the SML-built-in notion
- of \qt{bool}. This results in less readable code;
- additionally, eager evaluation may cause programs to
- loop or break which would perfectly terminate when
- the existing SML @{verbatim "bool"} would be used. To map
- the HOL @{typ bool} on SML @{verbatim "bool"}, we may use
- \qn{custom serialisations}:
-*}
-
-code_type %quotett bool
- (SML "bool")
-code_const %quotett True and False and "op \<and>"
- (SML "true" and "false" and "_ andalso _")
-
-text {*
- \noindent The @{command code_type} command takes a type constructor
- as arguments together with a list of custom serialisations.
- Each custom serialisation starts with a target language
- identifier followed by an expression, which during
- code serialisation is inserted whenever the type constructor
- would occur. For constants, @{command code_const} implements
- the corresponding mechanism. Each ``@{verbatim "_"}'' in
- a serialisation expression is treated as a placeholder
- for the type constructor's (the constant's) arguments.
-*}
-
-text %quote {*@{code_stmts in_interval (SML)}*}
-
-text {*
- \noindent This still is not perfect: the parentheses
- around the \qt{andalso} expression are superfluous.
- Though the serialiser
- by no means attempts to imitate the rich Isabelle syntax
- framework, it provides some common idioms, notably
- associative infixes with precedences which may be used here:
-*}
-
-code_const %quotett "op \<and>"
- (SML infixl 1 "andalso")
-
-text %quote {*@{code_stmts in_interval (SML)}*}
-
-text {*
- \noindent The attentive reader may ask how we assert that no generated
- code will accidentally overwrite. For this reason the serialiser has
- an internal table of identifiers which have to be avoided to be used
- for new declarations. Initially, this table typically contains the
- keywords of the target language. It can be extended manually, thus avoiding
- accidental overwrites, using the @{command "code_reserved"} command:
-*}
-
-code_reserved %quote "\<SML>" bool true false andalso
-
-text {*
- \noindent Next, we try to map HOL pairs to SML pairs, using the
- infix ``@{verbatim "*"}'' type constructor and parentheses:
-*}
-(*<*)
-code_type %invisible *
- (SML)
-code_const %invisible Pair
- (SML)
-(*>*)
-code_type %quotett *
- (SML infix 2 "*")
-code_const %quotett Pair
- (SML "!((_),/ (_))")
-
-text {*
- \noindent The initial bang ``@{verbatim "!"}'' tells the serialiser
- never to put
- parentheses around the whole expression (they are already present),
- while the parentheses around argument place holders
- tell not to put parentheses around the arguments.
- The slash ``@{verbatim "/"}'' (followed by arbitrary white space)
- inserts a space which may be used as a break if necessary
- during pretty printing.
-
- These examples give a glimpse what mechanisms
- custom serialisations provide; however their usage
- requires careful thinking in order not to introduce
- inconsistencies -- or, in other words:
- custom serialisations are completely axiomatic.
-
- A further noteworthy details is that any special
- character in a custom serialisation may be quoted
- using ``@{verbatim "'"}''; thus, in
- ``@{verbatim "fn '_ => _"}'' the first
- ``@{verbatim "_"}'' is a proper underscore while the
- second ``@{verbatim "_"}'' is a placeholder.
-*}
-
-
-subsection {* @{text Haskell} serialisation *}
-
-text {*
- For convenience, the default
- @{text HOL} setup for @{text Haskell} maps the @{class eq} class to
- its counterpart in @{text Haskell}, giving custom serialisations
- for the class @{class eq} (by command @{command code_class}) and its operation
- @{const HOL.eq}
-*}
-
-code_class %quotett eq
- (Haskell "Eq")
-
-code_const %quotett "op ="
- (Haskell infixl 4 "==")
-
-text {*
- \noindent A problem now occurs whenever a type which
- is an instance of @{class eq} in @{text HOL} is mapped
- on a @{text Haskell}-built-in type which is also an instance
- of @{text Haskell} @{text Eq}:
-*}
-
-typedecl %quote bar
-
-instantiation %quote bar :: eq
-begin
-
-definition %quote "eq_class.eq (x\<Colon>bar) y \<longleftrightarrow> x = y"
-
-instance %quote by default (simp add: eq_bar_def)
-
-end %quote (*<*)
-
-(*>*) code_type %quotett bar
- (Haskell "Integer")
-
-text {*
- \noindent The code generator would produce
- an additional instance, which of course is rejected by the @{text Haskell}
- compiler.
- To suppress this additional instance, use
- @{text "code_instance"}:
-*}
-
-code_instance %quotett bar :: eq
- (Haskell -)
-
-
-subsection {* Enhancing the target language context \label{sec:include} *}
-
-text {*
- In rare cases it is necessary to \emph{enrich} the context of a
- target language; this is accomplished using the @{command "code_include"}
- command:
-*}
-
-code_include %quotett Haskell "Errno"
-{*errno i = error ("Error number: " ++ show i)*}
-
-code_reserved %quotett Haskell Errno
-
-text {*
- \noindent Such named @{text include}s are then prepended to every generated code.
- Inspect such code in order to find out how @{command "code_include"} behaves
- with respect to a particular target language.
-*}
-
-end
--- a/doc-src/Codegen/Thy/Further.thy Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Codegen/Thy/Further.thy Mon May 11 17:20:52 2009 +0200
@@ -66,7 +66,7 @@
text {*
\noindent The soundness of the @{method eval} method depends crucially
on the correctness of the code generator; this is one of the reasons
- why you should not use adaption (see \secref{sec:adaption}) frivolously.
+ why you should not use adaptation (see \secref{sec:adaptation}) frivolously.
*}
subsection {* Code antiquotation *}
--- a/doc-src/Codegen/Thy/Introduction.thy Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Codegen/Thy/Introduction.thy Mon May 11 17:20:52 2009 +0200
@@ -28,8 +28,8 @@
This manifests in the structure of this tutorial: after a short
conceptual introduction with an example (\secref{sec:intro}),
we discuss the generic customisation facilities (\secref{sec:program}).
- A further section (\secref{sec:adaption}) is dedicated to the matter of
- \qn{adaption} to specific target language environments. After some
+ A further section (\secref{sec:adaptation}) is dedicated to the matter of
+ \qn{adaptation} to specific target language environments. After some
further issues (\secref{sec:further}) we conclude with an overview
of some ML programming interfaces (\secref{sec:ml}).
--- a/doc-src/Codegen/Thy/Program.thy Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Codegen/Thy/Program.thy Mon May 11 17:20:52 2009 +0200
@@ -323,7 +323,7 @@
*}
-subsection {* Equality and wellsortedness *}
+subsection {* Equality *}
text {*
Surely you have already noticed how equality is treated
@@ -358,60 +358,7 @@
manually like any other type class.
Though this @{text eq} class is designed to get rarely in
- the way, a subtlety
- enters the stage when definitions of overloaded constants
- are dependent on operational equality. For example, let
- us define a lexicographic ordering on tuples
- (also see theory @{theory Product_ord}):
-*}
-
-instantiation %quote "*" :: (order, order) order
-begin
-
-definition %quote [code del]:
- "x \<le> y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x \<le> snd y"
-
-definition %quote [code del]:
- "x < y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x < snd y"
-
-instance %quote proof
-qed (auto simp: less_eq_prod_def less_prod_def intro: order_less_trans)
-
-end %quote
-
-lemma %quote order_prod [code]:
- "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow>
- x1 < x2 \<or> x1 = x2 \<and> y1 < y2"
- "(x1 \<Colon> 'a\<Colon>order, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow>
- x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2"
- by (simp_all add: less_prod_def less_eq_prod_def)
-
-text {*
- \noindent Then code generation will fail. Why? The definition
- of @{term "op \<le>"} depends on equality on both arguments,
- which are polymorphic and impose an additional @{class eq}
- class constraint, which the preprocessor does not propagate
- (for technical reasons).
-
- The solution is to add @{class eq} explicitly to the first sort arguments in the
- code theorems:
-*}
-
-lemma %quote order_prod_code [code]:
- "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) < (x2, y2) \<longleftrightarrow>
- x1 < x2 \<or> x1 = x2 \<and> y1 < y2"
- "(x1 \<Colon> 'a\<Colon>{order, eq}, y1 \<Colon> 'b\<Colon>order) \<le> (x2, y2) \<longleftrightarrow>
- x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2"
- by (simp_all add: less_prod_def less_eq_prod_def)
-
-text {*
- \noindent Then code generation succeeds:
-*}
-
-text %quote {*@{code_stmts "op \<le> \<Colon> _ \<times> _ \<Rightarrow> _ \<times> _ \<Rightarrow> bool" (SML)}*}
-
-text {*
- In some cases, the automatically derived code equations
+ the way, in some cases the automatically derived code equations
for equality on a particular type may not be appropriate.
As example, watch the following datatype representing
monomorphic parametric types (where type constructors
--- a/doc-src/Codegen/Thy/ROOT.ML Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Codegen/Thy/ROOT.ML Mon May 11 17:20:52 2009 +0200
@@ -4,6 +4,6 @@
use_thy "Introduction";
use_thy "Program";
-use_thy "Adaption";
+use_thy "Adaptation";
use_thy "Further";
use_thy "ML";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc-src/Codegen/Thy/document/Adaptation.tex Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,642 @@
+%
+\begin{isabellebody}%
+\def\isabellecontext{Adaptation}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{theory}\isamarkupfalse%
+\ Adaptation\isanewline
+\isakeyword{imports}\ Setup\isanewline
+\isakeyword{begin}%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+\isanewline
+%
+\endisadelimtheory
+%
+\isadeliminvisible
+\isanewline
+%
+\endisadeliminvisible
+%
+\isataginvisible
+\isacommand{setup}\isamarkupfalse%
+\ {\isacharverbatimopen}\ Code{\isacharunderscore}Target{\isachardot}extend{\isacharunderscore}target\ {\isacharparenleft}{\isachardoublequote}{\isasymSML}{\isachardoublequote}{\isacharcomma}\ {\isacharparenleft}{\isachardoublequote}SML{\isachardoublequote}{\isacharcomma}\ K\ I{\isacharparenright}{\isacharparenright}\ {\isacharverbatimclose}%
+\endisataginvisible
+{\isafoldinvisible}%
+%
+\isadeliminvisible
+%
+\endisadeliminvisible
+%
+\isamarkupsection{Adaptation to target languages \label{sec:adaptation}%
+}
+\isamarkuptrue%
+%
+\isamarkupsubsection{Adapting code generation%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The aspects of code generation introduced so far have two aspects
+ in common:
+
+ \begin{itemize}
+ \item They act uniformly, without reference to a specific
+ target language.
+ \item They are \emph{safe} in the sense that as long as you trust
+ the code generator meta theory and implementation, you cannot
+ produce programs that yield results which are not derivable
+ in the logic.
+ \end{itemize}
+
+ \noindent In this section we will introduce means to \emph{adapt} the serialiser
+ to a specific target language, i.e.~to print program fragments
+ in a way which accommodates \qt{already existing} ingredients of
+ a target language environment, for three reasons:
+
+ \begin{itemize}
+ \item improving readability and aesthetics of generated code
+ \item gaining efficiency
+ \item interface with language parts which have no direct counterpart
+ in \isa{HOL} (say, imperative data structures)
+ \end{itemize}
+
+ \noindent Generally, you should avoid using those features yourself
+ \emph{at any cost}:
+
+ \begin{itemize}
+ \item The safe configuration methods act uniformly on every target language,
+ whereas for adaptation you have to treat each target language separate.
+ \item Application is extremely tedious since there is no abstraction
+ which would allow for a static check, making it easy to produce garbage.
+ \item More or less subtle errors can be introduced unconsciously.
+ \end{itemize}
+
+ \noindent However, even if you ought refrain from setting up adaptation
+ yourself, already the \isa{HOL} comes with some reasonable default
+ adaptations (say, using target language list syntax). There also some
+ common adaptation cases which you can setup by importing particular
+ library theories. In order to understand these, we provide some clues here;
+ these however are not supposed to replace a careful study of the sources.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsubsection{The adaptation principle%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+Figure \ref{fig:adaptation} illustrates what \qt{adaptation} is conceptually
+ supposed to be:
+
+ \begin{figure}[here]
+ \includegraphics{adaptation}
+ \caption{The adaptation principle}
+ \label{fig:adaptation}
+ \end{figure}
+
+ \noindent In the tame view, code generation acts as broker between
+ \isa{logic}, \isa{intermediate\ language} and
+ \isa{target\ language} by means of \isa{translation} and
+ \isa{serialisation}; for the latter, the serialiser has to observe
+ the structure of the \isa{language} itself plus some \isa{reserved}
+ keywords which have to be avoided for generated code.
+ However, if you consider \isa{adaptation} mechanisms, the code generated
+ by the serializer is just the tip of the iceberg:
+
+ \begin{itemize}
+ \item \isa{serialisation} can be \emph{parametrised} such that
+ logical entities are mapped to target-specific ones
+ (e.g. target-specific list syntax,
+ see also \secref{sec:adaptation_mechanisms})
+ \item Such parametrisations can involve references to a
+ target-specific standard \isa{library} (e.g. using
+ the \isa{Haskell} \verb|Maybe| type instead
+ of the \isa{HOL} \isa{option} type);
+ if such are used, the corresponding identifiers
+ (in our example, \verb|Maybe|, \verb|Nothing|
+ and \verb|Just|) also have to be considered \isa{reserved}.
+ \item Even more, the user can enrich the library of the
+ target-language by providing code snippets
+ (\qt{\isa{includes}}) which are prepended to
+ any generated code (see \secref{sec:include}); this typically
+ also involves further \isa{reserved} identifiers.
+ \end{itemize}
+
+ \noindent As figure \ref{fig:adaptation} illustrates, all these adaptation mechanisms
+ have to act consistently; it is at the discretion of the user
+ to take care for this.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsubsection{Common adaptation patterns%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The \hyperlink{theory.HOL}{\mbox{\isa{HOL}}} \hyperlink{theory.Main}{\mbox{\isa{Main}}} theory already provides a code
+ generator setup
+ which should be suitable for most applications. Common extensions
+ and modifications are available by certain theories of the \isa{HOL}
+ library; beside being useful in applications, they may serve
+ as a tutorial for customising the code generator setup (see below
+ \secref{sec:adaptation_mechanisms}).
+
+ \begin{description}
+
+ \item[\hyperlink{theory.Code-Integer}{\mbox{\isa{Code{\isacharunderscore}Integer}}}] represents \isa{HOL} integers by big
+ integer literals in target languages.
+ \item[\hyperlink{theory.Code-Char}{\mbox{\isa{Code{\isacharunderscore}Char}}}] represents \isa{HOL} characters by
+ character literals in target languages.
+ \item[\hyperlink{theory.Code-Char-chr}{\mbox{\isa{Code{\isacharunderscore}Char{\isacharunderscore}chr}}}] like \isa{Code{\isacharunderscore}Char},
+ but also offers treatment of character codes; includes
+ \hyperlink{theory.Code-Char}{\mbox{\isa{Code{\isacharunderscore}Char}}}.
+ \item[\hyperlink{theory.Efficient-Nat}{\mbox{\isa{Efficient{\isacharunderscore}Nat}}}] \label{eff_nat} implements natural numbers by integers,
+ which in general will result in higher efficiency; pattern
+ matching with \isa{{\isadigit{0}}} / \isa{Suc}
+ is eliminated; includes \hyperlink{theory.Code-Integer}{\mbox{\isa{Code{\isacharunderscore}Integer}}}
+ and \hyperlink{theory.Code-Index}{\mbox{\isa{Code{\isacharunderscore}Index}}}.
+ \item[\hyperlink{theory.Code-Index}{\mbox{\isa{Code{\isacharunderscore}Index}}}] provides an additional datatype
+ \isa{index} which is mapped to target-language built-in integers.
+ Useful for code setups which involve e.g. indexing of
+ target-language arrays.
+ \item[\hyperlink{theory.Code-Message}{\mbox{\isa{Code{\isacharunderscore}Message}}}] provides an additional datatype
+ \isa{message{\isacharunderscore}string} which is isomorphic to strings;
+ \isa{message{\isacharunderscore}string}s are mapped to target-language strings.
+ Useful for code setups which involve e.g. printing (error) messages.
+
+ \end{description}
+
+ \begin{warn}
+ When importing any of these theories, they should form the last
+ items in an import list. Since these theories adapt the
+ code generator setup in a non-conservative fashion,
+ strange effects may occur otherwise.
+ \end{warn}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsubsection{Parametrising serialisation \label{sec:adaptation_mechanisms}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+Consider the following function and its corresponding
+ SML code:%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\isatagquote
+\isacommand{primrec}\isamarkupfalse%
+\ in{\isacharunderscore}interval\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymtimes}\ nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
+\ \ {\isachardoublequoteopen}in{\isacharunderscore}interval\ {\isacharparenleft}k{\isacharcomma}\ l{\isacharparenright}\ n\ {\isasymlongleftrightarrow}\ k\ {\isasymle}\ n\ {\isasymand}\ n\ {\isasymle}\ l{\isachardoublequoteclose}%
+\endisatagquote
+{\isafoldquote}%
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\isadeliminvisible
+%
+\endisadeliminvisible
+%
+\isataginvisible
+%
+\endisataginvisible
+{\isafoldinvisible}%
+%
+\isadeliminvisible
+%
+\endisadeliminvisible
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\isatagquote
+%
+\begin{isamarkuptext}%
+\isatypewriter%
+\noindent%
+\hspace*{0pt}structure Example = \\
+\hspace*{0pt}struct\\
+\hspace*{0pt}\\
+\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
+\hspace*{0pt}\\
+\hspace*{0pt}datatype boola = True | False;\\
+\hspace*{0pt}\\
+\hspace*{0pt}fun anda x True = x\\
+\hspace*{0pt} ~| anda x False = False\\
+\hspace*{0pt} ~| anda True x = x\\
+\hspace*{0pt} ~| anda False x = False;\\
+\hspace*{0pt}\\
+\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
+\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = False\\
+\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
+\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = True;\\
+\hspace*{0pt}\\
+\hspace*{0pt}fun in{\char95}interval (k,~l) n = anda (less{\char95}eq{\char95}nat k n) (less{\char95}eq{\char95}nat n l);\\
+\hspace*{0pt}\\
+\hspace*{0pt}end;~(*struct Example*)%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagquote
+{\isafoldquote}%
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\begin{isamarkuptext}%
+\noindent Though this is correct code, it is a little bit unsatisfactory:
+ boolean values and operators are materialised as distinguished
+ entities with have nothing to do with the SML-built-in notion
+ of \qt{bool}. This results in less readable code;
+ additionally, eager evaluation may cause programs to
+ loop or break which would perfectly terminate when
+ the existing SML \verb|bool| would be used. To map
+ the HOL \isa{bool} on SML \verb|bool|, we may use
+ \qn{custom serialisations}:%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\isatagquotett
+\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
+\ bool\isanewline
+\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}bool{\isachardoublequoteclose}{\isacharparenright}\isanewline
+\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
+\ True\ \isakeyword{and}\ False\ \isakeyword{and}\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
+\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}true{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}false{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}{\isacharunderscore}\ andalso\ {\isacharunderscore}{\isachardoublequoteclose}{\isacharparenright}%
+\endisatagquotett
+{\isafoldquotett}%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\begin{isamarkuptext}%
+\noindent The \hyperlink{command.code-type}{\mbox{\isa{\isacommand{code{\isacharunderscore}type}}}} command takes a type constructor
+ as arguments together with a list of custom serialisations.
+ Each custom serialisation starts with a target language
+ identifier followed by an expression, which during
+ code serialisation is inserted whenever the type constructor
+ would occur. For constants, \hyperlink{command.code-const}{\mbox{\isa{\isacommand{code{\isacharunderscore}const}}}} implements
+ the corresponding mechanism. Each ``\verb|_|'' in
+ a serialisation expression is treated as a placeholder
+ for the type constructor's (the constant's) arguments.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\isatagquote
+%
+\begin{isamarkuptext}%
+\isatypewriter%
+\noindent%
+\hspace*{0pt}structure Example = \\
+\hspace*{0pt}struct\\
+\hspace*{0pt}\\
+\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
+\hspace*{0pt}\\
+\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
+\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = false\\
+\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
+\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = true;\\
+\hspace*{0pt}\\
+\hspace*{0pt}fun in{\char95}interval (k,~l) n = (less{\char95}eq{\char95}nat k n) andalso (less{\char95}eq{\char95}nat n l);\\
+\hspace*{0pt}\\
+\hspace*{0pt}end;~(*struct Example*)%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagquote
+{\isafoldquote}%
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\begin{isamarkuptext}%
+\noindent This still is not perfect: the parentheses
+ around the \qt{andalso} expression are superfluous.
+ Though the serialiser
+ by no means attempts to imitate the rich Isabelle syntax
+ framework, it provides some common idioms, notably
+ associative infixes with precedences which may be used here:%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\isatagquotett
+\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
+\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
+\ \ {\isacharparenleft}SML\ \isakeyword{infixl}\ {\isadigit{1}}\ {\isachardoublequoteopen}andalso{\isachardoublequoteclose}{\isacharparenright}%
+\endisatagquotett
+{\isafoldquotett}%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\isatagquote
+%
+\begin{isamarkuptext}%
+\isatypewriter%
+\noindent%
+\hspace*{0pt}structure Example = \\
+\hspace*{0pt}struct\\
+\hspace*{0pt}\\
+\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
+\hspace*{0pt}\\
+\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
+\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = false\\
+\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
+\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = true;\\
+\hspace*{0pt}\\
+\hspace*{0pt}fun in{\char95}interval (k,~l) n = less{\char95}eq{\char95}nat k n andalso less{\char95}eq{\char95}nat n l;\\
+\hspace*{0pt}\\
+\hspace*{0pt}end;~(*struct Example*)%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagquote
+{\isafoldquote}%
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\begin{isamarkuptext}%
+\noindent The attentive reader may ask how we assert that no generated
+ code will accidentally overwrite. For this reason the serialiser has
+ an internal table of identifiers which have to be avoided to be used
+ for new declarations. Initially, this table typically contains the
+ keywords of the target language. It can be extended manually, thus avoiding
+ accidental overwrites, using the \hyperlink{command.code-reserved}{\mbox{\isa{\isacommand{code{\isacharunderscore}reserved}}}} command:%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\isatagquote
+\isacommand{code{\isacharunderscore}reserved}\isamarkupfalse%
+\ {\isachardoublequoteopen}{\isasymSML}{\isachardoublequoteclose}\ bool\ true\ false\ andalso%
+\endisatagquote
+{\isafoldquote}%
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\begin{isamarkuptext}%
+\noindent Next, we try to map HOL pairs to SML pairs, using the
+ infix ``\verb|*|'' type constructor and parentheses:%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadeliminvisible
+%
+\endisadeliminvisible
+%
+\isataginvisible
+%
+\endisataginvisible
+{\isafoldinvisible}%
+%
+\isadeliminvisible
+%
+\endisadeliminvisible
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\isatagquotett
+\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
+\ {\isacharasterisk}\isanewline
+\ \ {\isacharparenleft}SML\ \isakeyword{infix}\ {\isadigit{2}}\ {\isachardoublequoteopen}{\isacharasterisk}{\isachardoublequoteclose}{\isacharparenright}\isanewline
+\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
+\ Pair\isanewline
+\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}{\isacharbang}{\isacharparenleft}{\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharcomma}{\isacharslash}\ {\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}%
+\endisatagquotett
+{\isafoldquotett}%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\begin{isamarkuptext}%
+\noindent The initial bang ``\verb|!|'' tells the serialiser
+ never to put
+ parentheses around the whole expression (they are already present),
+ while the parentheses around argument place holders
+ tell not to put parentheses around the arguments.
+ The slash ``\verb|/|'' (followed by arbitrary white space)
+ inserts a space which may be used as a break if necessary
+ during pretty printing.
+
+ These examples give a glimpse what mechanisms
+ custom serialisations provide; however their usage
+ requires careful thinking in order not to introduce
+ inconsistencies -- or, in other words:
+ custom serialisations are completely axiomatic.
+
+ A further noteworthy details is that any special
+ character in a custom serialisation may be quoted
+ using ``\verb|'|''; thus, in
+ ``\verb|fn '_ => _|'' the first
+ ``\verb|_|'' is a proper underscore while the
+ second ``\verb|_|'' is a placeholder.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsubsection{\isa{Haskell} serialisation%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+For convenience, the default
+ \isa{HOL} setup for \isa{Haskell} maps the \isa{eq} class to
+ its counterpart in \isa{Haskell}, giving custom serialisations
+ for the class \isa{eq} (by command \hyperlink{command.code-class}{\mbox{\isa{\isacommand{code{\isacharunderscore}class}}}}) and its operation
+ \isa{eq{\isacharunderscore}class{\isachardot}eq}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\isatagquotett
+\isacommand{code{\isacharunderscore}class}\isamarkupfalse%
+\ eq\isanewline
+\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Eq{\isachardoublequoteclose}{\isacharparenright}\isanewline
+\isanewline
+\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
+\ {\isachardoublequoteopen}op\ {\isacharequal}{\isachardoublequoteclose}\isanewline
+\ \ {\isacharparenleft}Haskell\ \isakeyword{infixl}\ {\isadigit{4}}\ {\isachardoublequoteopen}{\isacharequal}{\isacharequal}{\isachardoublequoteclose}{\isacharparenright}%
+\endisatagquotett
+{\isafoldquotett}%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\begin{isamarkuptext}%
+\noindent A problem now occurs whenever a type which
+ is an instance of \isa{eq} in \isa{HOL} is mapped
+ on a \isa{Haskell}-built-in type which is also an instance
+ of \isa{Haskell} \isa{Eq}:%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\isatagquote
+\isacommand{typedecl}\isamarkupfalse%
+\ bar\isanewline
+\isanewline
+\isacommand{instantiation}\isamarkupfalse%
+\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
+\isakeyword{begin}\isanewline
+\isanewline
+\isacommand{definition}\isamarkupfalse%
+\ {\isachardoublequoteopen}eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}x{\isasymColon}bar{\isacharparenright}\ y\ {\isasymlongleftrightarrow}\ x\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
+\isanewline
+\isacommand{instance}\isamarkupfalse%
+\ \isacommand{by}\isamarkupfalse%
+\ default\ {\isacharparenleft}simp\ add{\isacharcolon}\ eq{\isacharunderscore}bar{\isacharunderscore}def{\isacharparenright}\isanewline
+\isanewline
+\isacommand{end}\isamarkupfalse%
+%
+\endisatagquote
+{\isafoldquote}%
+%
+\isadelimquote
+%
+\endisadelimquote
+%
+\isadelimquotett
+\ %
+\endisadelimquotett
+%
+\isatagquotett
+\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
+\ bar\isanewline
+\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Integer{\isachardoublequoteclose}{\isacharparenright}%
+\endisatagquotett
+{\isafoldquotett}%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\begin{isamarkuptext}%
+\noindent The code generator would produce
+ an additional instance, which of course is rejected by the \isa{Haskell}
+ compiler.
+ To suppress this additional instance, use
+ \isa{code{\isacharunderscore}instance}:%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\isatagquotett
+\isacommand{code{\isacharunderscore}instance}\isamarkupfalse%
+\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
+\ \ {\isacharparenleft}Haskell\ {\isacharminus}{\isacharparenright}%
+\endisatagquotett
+{\isafoldquotett}%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\isamarkupsubsection{Enhancing the target language context \label{sec:include}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+In rare cases it is necessary to \emph{enrich} the context of a
+ target language; this is accomplished using the \hyperlink{command.code-include}{\mbox{\isa{\isacommand{code{\isacharunderscore}include}}}}
+ command:%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\isatagquotett
+\isacommand{code{\isacharunderscore}include}\isamarkupfalse%
+\ Haskell\ {\isachardoublequoteopen}Errno{\isachardoublequoteclose}\isanewline
+{\isacharverbatimopen}errno\ i\ {\isacharequal}\ error\ {\isacharparenleft}{\isachardoublequote}Error\ number{\isacharcolon}\ {\isachardoublequote}\ {\isacharplus}{\isacharplus}\ show\ i{\isacharparenright}{\isacharverbatimclose}\isanewline
+\isanewline
+\isacommand{code{\isacharunderscore}reserved}\isamarkupfalse%
+\ Haskell\ Errno%
+\endisatagquotett
+{\isafoldquotett}%
+%
+\isadelimquotett
+%
+\endisadelimquotett
+%
+\begin{isamarkuptext}%
+\noindent Such named \isa{include}s are then prepended to every generated code.
+ Inspect such code in order to find out how \hyperlink{command.code-include}{\mbox{\isa{\isacommand{code{\isacharunderscore}include}}}} behaves
+ with respect to a particular target language.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{end}\isamarkupfalse%
+%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+\isanewline
+\end{isabellebody}%
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "root"
+%%% End:
--- a/doc-src/Codegen/Thy/document/Adaption.tex Mon May 11 09:39:53 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,642 +0,0 @@
-%
-\begin{isabellebody}%
-\def\isabellecontext{Adaption}%
-%
-\isadelimtheory
-%
-\endisadelimtheory
-%
-\isatagtheory
-\isacommand{theory}\isamarkupfalse%
-\ Adaption\isanewline
-\isakeyword{imports}\ Setup\isanewline
-\isakeyword{begin}%
-\endisatagtheory
-{\isafoldtheory}%
-%
-\isadelimtheory
-\isanewline
-%
-\endisadelimtheory
-%
-\isadeliminvisible
-\isanewline
-%
-\endisadeliminvisible
-%
-\isataginvisible
-\isacommand{setup}\isamarkupfalse%
-\ {\isacharverbatimopen}\ Code{\isacharunderscore}Target{\isachardot}extend{\isacharunderscore}target\ {\isacharparenleft}{\isachardoublequote}{\isasymSML}{\isachardoublequote}{\isacharcomma}\ {\isacharparenleft}{\isachardoublequote}SML{\isachardoublequote}{\isacharcomma}\ K\ I{\isacharparenright}{\isacharparenright}\ {\isacharverbatimclose}%
-\endisataginvisible
-{\isafoldinvisible}%
-%
-\isadeliminvisible
-%
-\endisadeliminvisible
-%
-\isamarkupsection{Adaption to target languages \label{sec:adaption}%
-}
-\isamarkuptrue%
-%
-\isamarkupsubsection{Adapting code generation%
-}
-\isamarkuptrue%
-%
-\begin{isamarkuptext}%
-The aspects of code generation introduced so far have two aspects
- in common:
-
- \begin{itemize}
- \item They act uniformly, without reference to a specific
- target language.
- \item They are \emph{safe} in the sense that as long as you trust
- the code generator meta theory and implementation, you cannot
- produce programs that yield results which are not derivable
- in the logic.
- \end{itemize}
-
- \noindent In this section we will introduce means to \emph{adapt} the serialiser
- to a specific target language, i.e.~to print program fragments
- in a way which accommodates \qt{already existing} ingredients of
- a target language environment, for three reasons:
-
- \begin{itemize}
- \item improving readability and aesthetics of generated code
- \item gaining efficiency
- \item interface with language parts which have no direct counterpart
- in \isa{HOL} (say, imperative data structures)
- \end{itemize}
-
- \noindent Generally, you should avoid using those features yourself
- \emph{at any cost}:
-
- \begin{itemize}
- \item The safe configuration methods act uniformly on every target language,
- whereas for adaption you have to treat each target language separate.
- \item Application is extremely tedious since there is no abstraction
- which would allow for a static check, making it easy to produce garbage.
- \item More or less subtle errors can be introduced unconsciously.
- \end{itemize}
-
- \noindent However, even if you ought refrain from setting up adaption
- yourself, already the \isa{HOL} comes with some reasonable default
- adaptions (say, using target language list syntax). There also some
- common adaption cases which you can setup by importing particular
- library theories. In order to understand these, we provide some clues here;
- these however are not supposed to replace a careful study of the sources.%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isamarkupsubsection{The adaption principle%
-}
-\isamarkuptrue%
-%
-\begin{isamarkuptext}%
-Figure \ref{fig:adaption} illustrates what \qt{adaption} is conceptually
- supposed to be:
-
- \begin{figure}[here]
- \includegraphics{adaption}
- \caption{The adaption principle}
- \label{fig:adaption}
- \end{figure}
-
- \noindent In the tame view, code generation acts as broker between
- \isa{logic}, \isa{intermediate\ language} and
- \isa{target\ language} by means of \isa{translation} and
- \isa{serialisation}; for the latter, the serialiser has to observe
- the structure of the \isa{language} itself plus some \isa{reserved}
- keywords which have to be avoided for generated code.
- However, if you consider \isa{adaption} mechanisms, the code generated
- by the serializer is just the tip of the iceberg:
-
- \begin{itemize}
- \item \isa{serialisation} can be \emph{parametrised} such that
- logical entities are mapped to target-specific ones
- (e.g. target-specific list syntax,
- see also \secref{sec:adaption_mechanisms})
- \item Such parametrisations can involve references to a
- target-specific standard \isa{library} (e.g. using
- the \isa{Haskell} \verb|Maybe| type instead
- of the \isa{HOL} \isa{option} type);
- if such are used, the corresponding identifiers
- (in our example, \verb|Maybe|, \verb|Nothing|
- and \verb|Just|) also have to be considered \isa{reserved}.
- \item Even more, the user can enrich the library of the
- target-language by providing code snippets
- (\qt{\isa{includes}}) which are prepended to
- any generated code (see \secref{sec:include}); this typically
- also involves further \isa{reserved} identifiers.
- \end{itemize}
-
- \noindent As figure \ref{fig:adaption} illustrates, all these adaption mechanisms
- have to act consistently; it is at the discretion of the user
- to take care for this.%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isamarkupsubsection{Common adaption patterns%
-}
-\isamarkuptrue%
-%
-\begin{isamarkuptext}%
-The \hyperlink{theory.HOL}{\mbox{\isa{HOL}}} \hyperlink{theory.Main}{\mbox{\isa{Main}}} theory already provides a code
- generator setup
- which should be suitable for most applications. Common extensions
- and modifications are available by certain theories of the \isa{HOL}
- library; beside being useful in applications, they may serve
- as a tutorial for customising the code generator setup (see below
- \secref{sec:adaption_mechanisms}).
-
- \begin{description}
-
- \item[\hyperlink{theory.Code-Integer}{\mbox{\isa{Code{\isacharunderscore}Integer}}}] represents \isa{HOL} integers by big
- integer literals in target languages.
- \item[\hyperlink{theory.Code-Char}{\mbox{\isa{Code{\isacharunderscore}Char}}}] represents \isa{HOL} characters by
- character literals in target languages.
- \item[\hyperlink{theory.Code-Char-chr}{\mbox{\isa{Code{\isacharunderscore}Char{\isacharunderscore}chr}}}] like \isa{Code{\isacharunderscore}Char},
- but also offers treatment of character codes; includes
- \hyperlink{theory.Code-Char}{\mbox{\isa{Code{\isacharunderscore}Char}}}.
- \item[\hyperlink{theory.Efficient-Nat}{\mbox{\isa{Efficient{\isacharunderscore}Nat}}}] \label{eff_nat} implements natural numbers by integers,
- which in general will result in higher efficiency; pattern
- matching with \isa{{\isadigit{0}}} / \isa{Suc}
- is eliminated; includes \hyperlink{theory.Code-Integer}{\mbox{\isa{Code{\isacharunderscore}Integer}}}
- and \hyperlink{theory.Code-Index}{\mbox{\isa{Code{\isacharunderscore}Index}}}.
- \item[\hyperlink{theory.Code-Index}{\mbox{\isa{Code{\isacharunderscore}Index}}}] provides an additional datatype
- \isa{index} which is mapped to target-language built-in integers.
- Useful for code setups which involve e.g. indexing of
- target-language arrays.
- \item[\hyperlink{theory.Code-Message}{\mbox{\isa{Code{\isacharunderscore}Message}}}] provides an additional datatype
- \isa{message{\isacharunderscore}string} which is isomorphic to strings;
- \isa{message{\isacharunderscore}string}s are mapped to target-language strings.
- Useful for code setups which involve e.g. printing (error) messages.
-
- \end{description}
-
- \begin{warn}
- When importing any of these theories, they should form the last
- items in an import list. Since these theories adapt the
- code generator setup in a non-conservative fashion,
- strange effects may occur otherwise.
- \end{warn}%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isamarkupsubsection{Parametrising serialisation \label{sec:adaption_mechanisms}%
-}
-\isamarkuptrue%
-%
-\begin{isamarkuptext}%
-Consider the following function and its corresponding
- SML code:%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\isatagquote
-\isacommand{primrec}\isamarkupfalse%
-\ in{\isacharunderscore}interval\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymtimes}\ nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\ \isakeyword{where}\isanewline
-\ \ {\isachardoublequoteopen}in{\isacharunderscore}interval\ {\isacharparenleft}k{\isacharcomma}\ l{\isacharparenright}\ n\ {\isasymlongleftrightarrow}\ k\ {\isasymle}\ n\ {\isasymand}\ n\ {\isasymle}\ l{\isachardoublequoteclose}%
-\endisatagquote
-{\isafoldquote}%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\isadeliminvisible
-%
-\endisadeliminvisible
-%
-\isataginvisible
-%
-\endisataginvisible
-{\isafoldinvisible}%
-%
-\isadeliminvisible
-%
-\endisadeliminvisible
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\isatagquote
-%
-\begin{isamarkuptext}%
-\isatypewriter%
-\noindent%
-\hspace*{0pt}structure Example = \\
-\hspace*{0pt}struct\\
-\hspace*{0pt}\\
-\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
-\hspace*{0pt}\\
-\hspace*{0pt}datatype boola = True | False;\\
-\hspace*{0pt}\\
-\hspace*{0pt}fun anda x True = x\\
-\hspace*{0pt} ~| anda x False = False\\
-\hspace*{0pt} ~| anda True x = x\\
-\hspace*{0pt} ~| anda False x = False;\\
-\hspace*{0pt}\\
-\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
-\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = False\\
-\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
-\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = True;\\
-\hspace*{0pt}\\
-\hspace*{0pt}fun in{\char95}interval (k,~l) n = anda (less{\char95}eq{\char95}nat k n) (less{\char95}eq{\char95}nat n l);\\
-\hspace*{0pt}\\
-\hspace*{0pt}end;~(*struct Example*)%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\endisatagquote
-{\isafoldquote}%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\begin{isamarkuptext}%
-\noindent Though this is correct code, it is a little bit unsatisfactory:
- boolean values and operators are materialised as distinguished
- entities with have nothing to do with the SML-built-in notion
- of \qt{bool}. This results in less readable code;
- additionally, eager evaluation may cause programs to
- loop or break which would perfectly terminate when
- the existing SML \verb|bool| would be used. To map
- the HOL \isa{bool} on SML \verb|bool|, we may use
- \qn{custom serialisations}:%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\isatagquotett
-\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
-\ bool\isanewline
-\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}bool{\isachardoublequoteclose}{\isacharparenright}\isanewline
-\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
-\ True\ \isakeyword{and}\ False\ \isakeyword{and}\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
-\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}true{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}false{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}{\isacharunderscore}\ andalso\ {\isacharunderscore}{\isachardoublequoteclose}{\isacharparenright}%
-\endisatagquotett
-{\isafoldquotett}%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\begin{isamarkuptext}%
-\noindent The \hyperlink{command.code-type}{\mbox{\isa{\isacommand{code{\isacharunderscore}type}}}} command takes a type constructor
- as arguments together with a list of custom serialisations.
- Each custom serialisation starts with a target language
- identifier followed by an expression, which during
- code serialisation is inserted whenever the type constructor
- would occur. For constants, \hyperlink{command.code-const}{\mbox{\isa{\isacommand{code{\isacharunderscore}const}}}} implements
- the corresponding mechanism. Each ``\verb|_|'' in
- a serialisation expression is treated as a placeholder
- for the type constructor's (the constant's) arguments.%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\isatagquote
-%
-\begin{isamarkuptext}%
-\isatypewriter%
-\noindent%
-\hspace*{0pt}structure Example = \\
-\hspace*{0pt}struct\\
-\hspace*{0pt}\\
-\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
-\hspace*{0pt}\\
-\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
-\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = false\\
-\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
-\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = true;\\
-\hspace*{0pt}\\
-\hspace*{0pt}fun in{\char95}interval (k,~l) n = (less{\char95}eq{\char95}nat k n) andalso (less{\char95}eq{\char95}nat n l);\\
-\hspace*{0pt}\\
-\hspace*{0pt}end;~(*struct Example*)%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\endisatagquote
-{\isafoldquote}%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\begin{isamarkuptext}%
-\noindent This still is not perfect: the parentheses
- around the \qt{andalso} expression are superfluous.
- Though the serialiser
- by no means attempts to imitate the rich Isabelle syntax
- framework, it provides some common idioms, notably
- associative infixes with precedences which may be used here:%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\isatagquotett
-\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
-\ {\isachardoublequoteopen}op\ {\isasymand}{\isachardoublequoteclose}\isanewline
-\ \ {\isacharparenleft}SML\ \isakeyword{infixl}\ {\isadigit{1}}\ {\isachardoublequoteopen}andalso{\isachardoublequoteclose}{\isacharparenright}%
-\endisatagquotett
-{\isafoldquotett}%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\isatagquote
-%
-\begin{isamarkuptext}%
-\isatypewriter%
-\noindent%
-\hspace*{0pt}structure Example = \\
-\hspace*{0pt}struct\\
-\hspace*{0pt}\\
-\hspace*{0pt}datatype nat = Zero{\char95}nat | Suc of nat;\\
-\hspace*{0pt}\\
-\hspace*{0pt}fun less{\char95}nat m (Suc n) = less{\char95}eq{\char95}nat m n\\
-\hspace*{0pt} ~| less{\char95}nat n Zero{\char95}nat = false\\
-\hspace*{0pt}and less{\char95}eq{\char95}nat (Suc m) n = less{\char95}nat m n\\
-\hspace*{0pt} ~| less{\char95}eq{\char95}nat Zero{\char95}nat n = true;\\
-\hspace*{0pt}\\
-\hspace*{0pt}fun in{\char95}interval (k,~l) n = less{\char95}eq{\char95}nat k n andalso less{\char95}eq{\char95}nat n l;\\
-\hspace*{0pt}\\
-\hspace*{0pt}end;~(*struct Example*)%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\endisatagquote
-{\isafoldquote}%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\begin{isamarkuptext}%
-\noindent The attentive reader may ask how we assert that no generated
- code will accidentally overwrite. For this reason the serialiser has
- an internal table of identifiers which have to be avoided to be used
- for new declarations. Initially, this table typically contains the
- keywords of the target language. It can be extended manually, thus avoiding
- accidental overwrites, using the \hyperlink{command.code-reserved}{\mbox{\isa{\isacommand{code{\isacharunderscore}reserved}}}} command:%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\isatagquote
-\isacommand{code{\isacharunderscore}reserved}\isamarkupfalse%
-\ {\isachardoublequoteopen}{\isasymSML}{\isachardoublequoteclose}\ bool\ true\ false\ andalso%
-\endisatagquote
-{\isafoldquote}%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\begin{isamarkuptext}%
-\noindent Next, we try to map HOL pairs to SML pairs, using the
- infix ``\verb|*|'' type constructor and parentheses:%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadeliminvisible
-%
-\endisadeliminvisible
-%
-\isataginvisible
-%
-\endisataginvisible
-{\isafoldinvisible}%
-%
-\isadeliminvisible
-%
-\endisadeliminvisible
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\isatagquotett
-\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
-\ {\isacharasterisk}\isanewline
-\ \ {\isacharparenleft}SML\ \isakeyword{infix}\ {\isadigit{2}}\ {\isachardoublequoteopen}{\isacharasterisk}{\isachardoublequoteclose}{\isacharparenright}\isanewline
-\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
-\ Pair\isanewline
-\ \ {\isacharparenleft}SML\ {\isachardoublequoteopen}{\isacharbang}{\isacharparenleft}{\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharcomma}{\isacharslash}\ {\isacharparenleft}{\isacharunderscore}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}%
-\endisatagquotett
-{\isafoldquotett}%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\begin{isamarkuptext}%
-\noindent The initial bang ``\verb|!|'' tells the serialiser
- never to put
- parentheses around the whole expression (they are already present),
- while the parentheses around argument place holders
- tell not to put parentheses around the arguments.
- The slash ``\verb|/|'' (followed by arbitrary white space)
- inserts a space which may be used as a break if necessary
- during pretty printing.
-
- These examples give a glimpse what mechanisms
- custom serialisations provide; however their usage
- requires careful thinking in order not to introduce
- inconsistencies -- or, in other words:
- custom serialisations are completely axiomatic.
-
- A further noteworthy details is that any special
- character in a custom serialisation may be quoted
- using ``\verb|'|''; thus, in
- ``\verb|fn '_ => _|'' the first
- ``\verb|_|'' is a proper underscore while the
- second ``\verb|_|'' is a placeholder.%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isamarkupsubsection{\isa{Haskell} serialisation%
-}
-\isamarkuptrue%
-%
-\begin{isamarkuptext}%
-For convenience, the default
- \isa{HOL} setup for \isa{Haskell} maps the \isa{eq} class to
- its counterpart in \isa{Haskell}, giving custom serialisations
- for the class \isa{eq} (by command \hyperlink{command.code-class}{\mbox{\isa{\isacommand{code{\isacharunderscore}class}}}}) and its operation
- \isa{eq{\isacharunderscore}class{\isachardot}eq}%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\isatagquotett
-\isacommand{code{\isacharunderscore}class}\isamarkupfalse%
-\ eq\isanewline
-\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Eq{\isachardoublequoteclose}{\isacharparenright}\isanewline
-\isanewline
-\isacommand{code{\isacharunderscore}const}\isamarkupfalse%
-\ {\isachardoublequoteopen}op\ {\isacharequal}{\isachardoublequoteclose}\isanewline
-\ \ {\isacharparenleft}Haskell\ \isakeyword{infixl}\ {\isadigit{4}}\ {\isachardoublequoteopen}{\isacharequal}{\isacharequal}{\isachardoublequoteclose}{\isacharparenright}%
-\endisatagquotett
-{\isafoldquotett}%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\begin{isamarkuptext}%
-\noindent A problem now occurs whenever a type which
- is an instance of \isa{eq} in \isa{HOL} is mapped
- on a \isa{Haskell}-built-in type which is also an instance
- of \isa{Haskell} \isa{Eq}:%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\isatagquote
-\isacommand{typedecl}\isamarkupfalse%
-\ bar\isanewline
-\isanewline
-\isacommand{instantiation}\isamarkupfalse%
-\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
-\isakeyword{begin}\isanewline
-\isanewline
-\isacommand{definition}\isamarkupfalse%
-\ {\isachardoublequoteopen}eq{\isacharunderscore}class{\isachardot}eq\ {\isacharparenleft}x{\isasymColon}bar{\isacharparenright}\ y\ {\isasymlongleftrightarrow}\ x\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
-\isanewline
-\isacommand{instance}\isamarkupfalse%
-\ \isacommand{by}\isamarkupfalse%
-\ default\ {\isacharparenleft}simp\ add{\isacharcolon}\ eq{\isacharunderscore}bar{\isacharunderscore}def{\isacharparenright}\isanewline
-\isanewline
-\isacommand{end}\isamarkupfalse%
-%
-\endisatagquote
-{\isafoldquote}%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\isadelimquotett
-\ %
-\endisadelimquotett
-%
-\isatagquotett
-\isacommand{code{\isacharunderscore}type}\isamarkupfalse%
-\ bar\isanewline
-\ \ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}Integer{\isachardoublequoteclose}{\isacharparenright}%
-\endisatagquotett
-{\isafoldquotett}%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\begin{isamarkuptext}%
-\noindent The code generator would produce
- an additional instance, which of course is rejected by the \isa{Haskell}
- compiler.
- To suppress this additional instance, use
- \isa{code{\isacharunderscore}instance}:%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\isatagquotett
-\isacommand{code{\isacharunderscore}instance}\isamarkupfalse%
-\ bar\ {\isacharcolon}{\isacharcolon}\ eq\isanewline
-\ \ {\isacharparenleft}Haskell\ {\isacharminus}{\isacharparenright}%
-\endisatagquotett
-{\isafoldquotett}%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\isamarkupsubsection{Enhancing the target language context \label{sec:include}%
-}
-\isamarkuptrue%
-%
-\begin{isamarkuptext}%
-In rare cases it is necessary to \emph{enrich} the context of a
- target language; this is accomplished using the \hyperlink{command.code-include}{\mbox{\isa{\isacommand{code{\isacharunderscore}include}}}}
- command:%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\isatagquotett
-\isacommand{code{\isacharunderscore}include}\isamarkupfalse%
-\ Haskell\ {\isachardoublequoteopen}Errno{\isachardoublequoteclose}\isanewline
-{\isacharverbatimopen}errno\ i\ {\isacharequal}\ error\ {\isacharparenleft}{\isachardoublequote}Error\ number{\isacharcolon}\ {\isachardoublequote}\ {\isacharplus}{\isacharplus}\ show\ i{\isacharparenright}{\isacharverbatimclose}\isanewline
-\isanewline
-\isacommand{code{\isacharunderscore}reserved}\isamarkupfalse%
-\ Haskell\ Errno%
-\endisatagquotett
-{\isafoldquotett}%
-%
-\isadelimquotett
-%
-\endisadelimquotett
-%
-\begin{isamarkuptext}%
-\noindent Such named \isa{include}s are then prepended to every generated code.
- Inspect such code in order to find out how \hyperlink{command.code-include}{\mbox{\isa{\isacommand{code{\isacharunderscore}include}}}} behaves
- with respect to a particular target language.%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimtheory
-%
-\endisadelimtheory
-%
-\isatagtheory
-\isacommand{end}\isamarkupfalse%
-%
-\endisatagtheory
-{\isafoldtheory}%
-%
-\isadelimtheory
-%
-\endisadelimtheory
-\isanewline
-\end{isabellebody}%
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "root"
-%%% End:
--- a/doc-src/Codegen/Thy/document/Further.tex Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Codegen/Thy/document/Further.tex Mon May 11 17:20:52 2009 +0200
@@ -132,7 +132,7 @@
\begin{isamarkuptext}%
\noindent The soundness of the \hyperlink{method.eval}{\mbox{\isa{eval}}} method depends crucially
on the correctness of the code generator; this is one of the reasons
- why you should not use adaption (see \secref{sec:adaption}) frivolously.%
+ why you should not use adaptation (see \secref{sec:adaptation}) frivolously.%
\end{isamarkuptext}%
\isamarkuptrue%
%
--- a/doc-src/Codegen/Thy/document/Introduction.tex Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Codegen/Thy/document/Introduction.tex Mon May 11 17:20:52 2009 +0200
@@ -46,8 +46,8 @@
This manifests in the structure of this tutorial: after a short
conceptual introduction with an example (\secref{sec:intro}),
we discuss the generic customisation facilities (\secref{sec:program}).
- A further section (\secref{sec:adaption}) is dedicated to the matter of
- \qn{adaption} to specific target language environments. After some
+ A further section (\secref{sec:adaptation}) is dedicated to the matter of
+ \qn{adaptation} to specific target language environments. After some
further issues (\secref{sec:further}) we conclude with an overview
of some ML programming interfaces (\secref{sec:ml}).
@@ -229,7 +229,7 @@
\hspace*{0pt}module Example where {\char123}\\
\hspace*{0pt}\\
\hspace*{0pt}\\
-\hspace*{0pt}foldla ::~forall a b.~(a -> b -> a) -> a -> [b] -> a;\\
+\hspace*{0pt}foldla ::~forall a{\char95}1 b{\char95}1.~(a{\char95}1 -> b{\char95}1 -> a{\char95}1) -> a{\char95}1 -> [b{\char95}1] -> a{\char95}1;\\
\hspace*{0pt}foldla f a [] = a;\\
\hspace*{0pt}foldla f a (x :~xs) = foldla f (f a x) xs;\\
\hspace*{0pt}\\
--- a/doc-src/Codegen/Thy/document/Program.tex Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Codegen/Thy/document/Program.tex Mon May 11 17:20:52 2009 +0200
@@ -714,7 +714,7 @@
\end{isamarkuptext}%
\isamarkuptrue%
%
-\isamarkupsubsection{Equality and wellsortedness%
+\isamarkupsubsection{Equality%
}
\isamarkuptrue%
%
@@ -766,10 +766,10 @@
\hspace*{0pt}type 'a eq = {\char123}eq :~'a -> 'a -> bool{\char125};\\
\hspace*{0pt}fun eq (A{\char95}:'a eq) = {\char35}eq A{\char95};\\
\hspace*{0pt}\\
-\hspace*{0pt}fun eqop A{\char95}~a b = eq A{\char95}~a b;\\
+\hspace*{0pt}fun eqa A{\char95}~a b = eq A{\char95}~a b;\\
\hspace*{0pt}\\
\hspace*{0pt}fun member A{\char95}~x [] = false\\
-\hspace*{0pt} ~| member A{\char95}~x (y ::~ys) = eqop A{\char95}~x y orelse member A{\char95}~x ys;\\
+\hspace*{0pt} ~| member A{\char95}~x (y ::~ys) = eqa A{\char95}~x y orelse member A{\char95}~x ys;\\
\hspace*{0pt}\\
\hspace*{0pt}fun collect{\char95}duplicates A{\char95}~xs ys [] = xs\\
\hspace*{0pt} ~| collect{\char95}duplicates A{\char95}~xs ys (z ::~zs) =\\
@@ -801,141 +801,7 @@
manually like any other type class.
Though this \isa{eq} class is designed to get rarely in
- the way, a subtlety
- enters the stage when definitions of overloaded constants
- are dependent on operational equality. For example, let
- us define a lexicographic ordering on tuples
- (also see theory \hyperlink{theory.Product-ord}{\mbox{\isa{Product{\isacharunderscore}ord}}}):%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\isatagquote
-\isacommand{instantiation}\isamarkupfalse%
-\ {\isachardoublequoteopen}{\isacharasterisk}{\isachardoublequoteclose}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}order{\isacharcomma}\ order{\isacharparenright}\ order\isanewline
-\isakeyword{begin}\isanewline
-\isanewline
-\isacommand{definition}\isamarkupfalse%
-\ {\isacharbrackleft}code\ del{\isacharbrackright}{\isacharcolon}\isanewline
-\ \ {\isachardoublequoteopen}x\ {\isasymle}\ y\ {\isasymlongleftrightarrow}\ fst\ x\ {\isacharless}\ fst\ y\ {\isasymor}\ fst\ x\ {\isacharequal}\ fst\ y\ {\isasymand}\ snd\ x\ {\isasymle}\ snd\ y{\isachardoublequoteclose}\isanewline
-\isanewline
-\isacommand{definition}\isamarkupfalse%
-\ {\isacharbrackleft}code\ del{\isacharbrackright}{\isacharcolon}\isanewline
-\ \ {\isachardoublequoteopen}x\ {\isacharless}\ y\ {\isasymlongleftrightarrow}\ fst\ x\ {\isacharless}\ fst\ y\ {\isasymor}\ fst\ x\ {\isacharequal}\ fst\ y\ {\isasymand}\ snd\ x\ {\isacharless}\ snd\ y{\isachardoublequoteclose}\isanewline
-\isanewline
-\isacommand{instance}\isamarkupfalse%
-\ \isacommand{proof}\isamarkupfalse%
-\isanewline
-\isacommand{qed}\isamarkupfalse%
-\ {\isacharparenleft}auto\ simp{\isacharcolon}\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}prod{\isacharunderscore}def\ intro{\isacharcolon}\ order{\isacharunderscore}less{\isacharunderscore}trans{\isacharparenright}\isanewline
-\isanewline
-\isacommand{end}\isamarkupfalse%
-\isanewline
-\isanewline
-\isacommand{lemma}\isamarkupfalse%
-\ order{\isacharunderscore}prod\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
-\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}order{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
-\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
-\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}order{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
-\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
-\ \ \isacommand{by}\isamarkupfalse%
-\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ less{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def{\isacharparenright}%
-\endisatagquote
-{\isafoldquote}%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\begin{isamarkuptext}%
-\noindent Then code generation will fail. Why? The definition
- of \isa{op\ {\isasymle}} depends on equality on both arguments,
- which are polymorphic and impose an additional \isa{eq}
- class constraint, which the preprocessor does not propagate
- (for technical reasons).
-
- The solution is to add \isa{eq} explicitly to the first sort arguments in the
- code theorems:%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\isatagquote
-\isacommand{lemma}\isamarkupfalse%
-\ order{\isacharunderscore}prod{\isacharunderscore}code\ {\isacharbrackleft}code{\isacharbrackright}{\isacharcolon}\isanewline
-\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}order{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isacharless}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
-\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isacharless}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
-\ \ {\isachardoublequoteopen}{\isacharparenleft}x{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}a{\isasymColon}{\isacharbraceleft}order{\isacharcomma}\ eq{\isacharbraceright}{\isacharcomma}\ y{\isadigit{1}}\ {\isasymColon}\ {\isacharprime}b{\isasymColon}order{\isacharparenright}\ {\isasymle}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isasymlongleftrightarrow}\isanewline
-\ \ \ \ \ x{\isadigit{1}}\ {\isacharless}\ x{\isadigit{2}}\ {\isasymor}\ x{\isadigit{1}}\ {\isacharequal}\ x{\isadigit{2}}\ {\isasymand}\ y{\isadigit{1}}\ {\isasymle}\ y{\isadigit{2}}{\isachardoublequoteclose}\isanewline
-\ \ \isacommand{by}\isamarkupfalse%
-\ {\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}\ less{\isacharunderscore}prod{\isacharunderscore}def\ less{\isacharunderscore}eq{\isacharunderscore}prod{\isacharunderscore}def{\isacharparenright}%
-\endisatagquote
-{\isafoldquote}%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\begin{isamarkuptext}%
-\noindent Then code generation succeeds:%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\isatagquote
-%
-\begin{isamarkuptext}%
-\isatypewriter%
-\noindent%
-\hspace*{0pt}structure Example = \\
-\hspace*{0pt}struct\\
-\hspace*{0pt}\\
-\hspace*{0pt}type 'a eq = {\char123}eq :~'a -> 'a -> bool{\char125};\\
-\hspace*{0pt}fun eq (A{\char95}:'a eq) = {\char35}eq A{\char95};\\
-\hspace*{0pt}\\
-\hspace*{0pt}type 'a ord = {\char123}less{\char95}eq :~'a -> 'a -> bool,~less :~'a -> 'a -> bool{\char125};\\
-\hspace*{0pt}fun less{\char95}eq (A{\char95}:'a ord) = {\char35}less{\char95}eq A{\char95};\\
-\hspace*{0pt}fun less (A{\char95}:'a ord) = {\char35}less A{\char95};\\
-\hspace*{0pt}\\
-\hspace*{0pt}fun eqop A{\char95}~a b = eq A{\char95}~a b;\\
-\hspace*{0pt}\\
-\hspace*{0pt}type 'a preorder = {\char123}Orderings{\char95}{\char95}ord{\char95}preorder :~'a ord{\char125};\\
-\hspace*{0pt}fun ord{\char95}preorder (A{\char95}:'a preorder) = {\char35}Orderings{\char95}{\char95}ord{\char95}preorder A{\char95};\\
-\hspace*{0pt}\\
-\hspace*{0pt}type 'a order = {\char123}Orderings{\char95}{\char95}preorder{\char95}order :~'a preorder{\char125};\\
-\hspace*{0pt}fun preorder{\char95}order (A{\char95}:'a order) = {\char35}Orderings{\char95}{\char95}preorder{\char95}order A{\char95};\\
-\hspace*{0pt}\\
-\hspace*{0pt}fun less{\char95}eqa (A1{\char95},~A2{\char95}) B{\char95}~(x1,~y1) (x2,~y2) =\\
-\hspace*{0pt} ~less ((ord{\char95}preorder o preorder{\char95}order) A2{\char95}) x1 x2 orelse\\
-\hspace*{0pt} ~~~eqop A1{\char95}~x1 x2 andalso\\
-\hspace*{0pt} ~~~~~less{\char95}eq ((ord{\char95}preorder o preorder{\char95}order) B{\char95}) y1 y2\\
-\hspace*{0pt} ~| less{\char95}eqa (A1{\char95},~A2{\char95}) B{\char95}~(x1,~y1) (x2,~y2) =\\
-\hspace*{0pt} ~~~less ((ord{\char95}preorder o preorder{\char95}order) A2{\char95}) x1 x2 orelse\\
-\hspace*{0pt} ~~~~~eqop A1{\char95}~x1 x2 andalso\\
-\hspace*{0pt} ~~~~~~~less{\char95}eq ((ord{\char95}preorder o preorder{\char95}order) B{\char95}) y1 y2;\\
-\hspace*{0pt}\\
-\hspace*{0pt}end;~(*struct Example*)%
-\end{isamarkuptext}%
-\isamarkuptrue%
-%
-\endisatagquote
-{\isafoldquote}%
-%
-\isadelimquote
-%
-\endisadelimquote
-%
-\begin{isamarkuptext}%
-In some cases, the automatically derived code equations
+ the way, in some cases the automatically derived code equations
for equality on a particular type may not be appropriate.
As example, watch the following datatype representing
monomorphic parametric types (where type constructors
--- a/doc-src/Codegen/Thy/examples/Example.hs Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Codegen/Thy/examples/Example.hs Mon May 11 17:20:52 2009 +0200
@@ -3,7 +3,7 @@
module Example where {
-foldla :: forall a b. (a -> b -> a) -> a -> [b] -> a;
+foldla :: forall a_1 b_1. (a_1 -> b_1 -> a_1) -> a_1 -> [b_1] -> a_1;
foldla f a [] = a;
foldla f a (x : xs) = foldla f (f a x) xs;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc-src/Codegen/Thy/pictures/adaptation.tex Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,52 @@
+
+\documentclass[12pt]{article}
+\usepackage{tikz}
+
+\begin{document}
+
+\thispagestyle{empty}
+\setlength{\fboxrule}{0.01pt}
+\setlength{\fboxsep}{4pt}
+
+\fcolorbox{white}{white}{
+
+\begin{tikzpicture}[scale = 0.5]
+ \tikzstyle water=[color = blue, thick]
+ \tikzstyle ice=[color = black, very thick, cap = round, join = round, fill = white]
+ \tikzstyle process=[color = green, semithick, ->]
+ \tikzstyle adaptation=[color = red, semithick, ->]
+ \tikzstyle target=[color = black]
+ \foreach \x in {0, ..., 24}
+ \draw[style=water] (\x, 0.25) sin + (0.25, 0.25) cos + (0.25, -0.25) sin
+ + (0.25, -0.25) cos + (0.25, 0.25);
+ \draw[style=ice] (1, 0) --
+ (3, 6) node[above, fill=white] {logic} -- (5, 0) -- cycle;
+ \draw[style=ice] (9, 0) --
+ (11, 6) node[above, fill=white] {intermediate language} -- (13, 0) -- cycle;
+ \draw[style=ice] (15, -6) --
+ (19, 6) node[above, fill=white] {target language} -- (23, -6) -- cycle;
+ \draw[style=process]
+ (3.5, 3) .. controls (7, 5) .. node[fill=white] {translation} (10.5, 3);
+ \draw[style=process]
+ (11.5, 3) .. controls (15, 5) .. node[fill=white] (serialisation) {serialisation} (18.5, 3);
+ \node (adaptation) at (11, -2) [style=adaptation] {adaptation};
+ \node at (19, 3) [rotate=90] {generated};
+ \node at (19.5, -5) {language};
+ \node at (19.5, -3) {library};
+ \node (includes) at (19.5, -1) {includes};
+ \node (reserved) at (16.5, -3) [rotate=72] {reserved}; % proper 71.57
+ \draw[style=process]
+ (includes) -- (serialisation);
+ \draw[style=process]
+ (reserved) -- (serialisation);
+ \draw[style=adaptation]
+ (adaptation) -- (serialisation);
+ \draw[style=adaptation]
+ (adaptation) -- (includes);
+ \draw[style=adaptation]
+ (adaptation) -- (reserved);
+\end{tikzpicture}
+
+}
+
+\end{document}
--- a/doc-src/Codegen/Thy/pictures/adaption.tex Mon May 11 09:39:53 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-
-\documentclass[12pt]{article}
-\usepackage{tikz}
-
-\begin{document}
-
-\thispagestyle{empty}
-\setlength{\fboxrule}{0.01pt}
-\setlength{\fboxsep}{4pt}
-
-\fcolorbox{white}{white}{
-
-\begin{tikzpicture}[scale = 0.5]
- \tikzstyle water=[color = blue, thick]
- \tikzstyle ice=[color = black, very thick, cap = round, join = round, fill = white]
- \tikzstyle process=[color = green, semithick, ->]
- \tikzstyle adaption=[color = red, semithick, ->]
- \tikzstyle target=[color = black]
- \foreach \x in {0, ..., 24}
- \draw[style=water] (\x, 0.25) sin + (0.25, 0.25) cos + (0.25, -0.25) sin
- + (0.25, -0.25) cos + (0.25, 0.25);
- \draw[style=ice] (1, 0) --
- (3, 6) node[above, fill=white] {logic} -- (5, 0) -- cycle;
- \draw[style=ice] (9, 0) --
- (11, 6) node[above, fill=white] {intermediate language} -- (13, 0) -- cycle;
- \draw[style=ice] (15, -6) --
- (19, 6) node[above, fill=white] {target language} -- (23, -6) -- cycle;
- \draw[style=process]
- (3.5, 3) .. controls (7, 5) .. node[fill=white] {translation} (10.5, 3);
- \draw[style=process]
- (11.5, 3) .. controls (15, 5) .. node[fill=white] (serialisation) {serialisation} (18.5, 3);
- \node (adaption) at (11, -2) [style=adaption] {adaption};
- \node at (19, 3) [rotate=90] {generated};
- \node at (19.5, -5) {language};
- \node at (19.5, -3) {library};
- \node (includes) at (19.5, -1) {includes};
- \node (reserved) at (16.5, -3) [rotate=72] {reserved}; % proper 71.57
- \draw[style=process]
- (includes) -- (serialisation);
- \draw[style=process]
- (reserved) -- (serialisation);
- \draw[style=adaption]
- (adaption) -- (serialisation);
- \draw[style=adaption]
- (adaption) -- (includes);
- \draw[style=adaption]
- (adaption) -- (reserved);
-\end{tikzpicture}
-
-}
-
-\end{document}
--- a/doc-src/Codegen/codegen.tex Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Codegen/codegen.tex Mon May 11 17:20:52 2009 +0200
@@ -32,7 +32,7 @@
\input{Thy/document/Introduction.tex}
\input{Thy/document/Program.tex}
-\input{Thy/document/Adaption.tex}
+\input{Thy/document/Adaptation.tex}
\input{Thy/document/Further.tex}
\input{Thy/document/ML.tex}
--- a/doc-src/IsarRef/Thy/Spec.thy Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/IsarRef/Thy/Spec.thy Mon May 11 17:20:52 2009 +0200
@@ -752,7 +752,11 @@
text {*
Isabelle/Pure's definitional schemes support certain forms of
- overloading (see \secref{sec:consts}). At most occassions
+ overloading (see \secref{sec:consts}). Overloading means that a
+ constant being declared as @{text "c :: \<alpha> decl"} may be
+ defined separately on type instances
+ @{text "c :: (\<beta>\<^sub>1, \<dots>, \<beta>\<^sub>n) t decl"}
+ for each type constructor @{text t}. At most occassions
overloading will be used in a Haskell-like fashion together with
type classes by means of @{command "instantiation"} (see
\secref{sec:class}). Sometimes low-level overloading is desirable.
@@ -782,7 +786,8 @@
A @{text "(unchecked)"} option disables global dependency checks for
the corresponding definition, which is occasionally useful for
- exotic overloading. It is at the discretion of the user to avoid
+ exotic overloading (see \secref{sec:consts} for a precise description).
+ It is at the discretion of the user to avoid
malformed theory specifications!
\end{description}
@@ -1065,10 +1070,7 @@
\end{itemize}
- Overloading means that a constant being declared as @{text "c :: \<alpha>
- decl"} may be defined separately on type instances @{text "c ::
- (\<beta>\<^sub>1, \<dots>, \<beta>\<^sub>n) t decl"} for each type constructor @{text
- t}. The right-hand side may mention overloaded constants
+ The right-hand side of overloaded definitions may mention overloaded constants
recursively at type instances corresponding to the immediate
argument types @{text "\<beta>\<^sub>1, \<dots>, \<beta>\<^sub>n"}. Incomplete
specification patterns impose global constraints on all occurrences,
--- a/doc-src/IsarRef/Thy/document/Spec.tex Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/IsarRef/Thy/document/Spec.tex Mon May 11 17:20:52 2009 +0200
@@ -759,7 +759,11 @@
%
\begin{isamarkuptext}%
Isabelle/Pure's definitional schemes support certain forms of
- overloading (see \secref{sec:consts}). At most occassions
+ overloading (see \secref{sec:consts}). Overloading means that a
+ constant being declared as \isa{{\isachardoublequote}c\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ decl{\isachardoublequote}} may be
+ defined separately on type instances
+ \isa{{\isachardoublequote}c\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}{\isasymbeta}\isactrlsub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymbeta}\isactrlsub n{\isacharparenright}\ t\ decl{\isachardoublequote}}
+ for each type constructor \isa{t}. At most occassions
overloading will be used in a Haskell-like fashion together with
type classes by means of \hyperlink{command.instantiation}{\mbox{\isa{\isacommand{instantiation}}}} (see
\secref{sec:class}). Sometimes low-level overloading is desirable.
@@ -788,7 +792,8 @@
A \isa{{\isachardoublequote}{\isacharparenleft}unchecked{\isacharparenright}{\isachardoublequote}} option disables global dependency checks for
the corresponding definition, which is occasionally useful for
- exotic overloading. It is at the discretion of the user to avoid
+ exotic overloading (see \secref{sec:consts} for a precise description).
+ It is at the discretion of the user to avoid
malformed theory specifications!
\end{description}%
@@ -1092,7 +1097,7 @@
\end{itemize}
- Overloading means that a constant being declared as \isa{{\isachardoublequote}c\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ decl{\isachardoublequote}} may be defined separately on type instances \isa{{\isachardoublequote}c\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}{\isasymbeta}\isactrlsub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymbeta}\isactrlsub n{\isacharparenright}\ t\ decl{\isachardoublequote}} for each type constructor \isa{t}. The right-hand side may mention overloaded constants
+ The right-hand side of overloaded definitions may mention overloaded constants
recursively at type instances corresponding to the immediate
argument types \isa{{\isachardoublequote}{\isasymbeta}\isactrlsub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymbeta}\isactrlsub n{\isachardoublequote}}. Incomplete
specification patterns impose global constraints on all occurrences,
--- a/doc-src/Main/Docs/Main_Doc.thy Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Main/Docs/Main_Doc.thy Mon May 11 17:20:52 2009 +0200
@@ -268,6 +268,7 @@
@{const Transitive_Closure.rtrancl} & @{term_type_only Transitive_Closure.rtrancl "('a*'a)set\<Rightarrow>('a*'a)set"}\\
@{const Transitive_Closure.trancl} & @{term_type_only Transitive_Closure.trancl "('a*'a)set\<Rightarrow>('a*'a)set"}\\
@{const Transitive_Closure.reflcl} & @{term_type_only Transitive_Closure.reflcl "('a*'a)set\<Rightarrow>('a*'a)set"}\\
+@{const compower} & @{term_type_only "op ^^ :: ('a*'a)set\<Rightarrow>nat\<Rightarrow>('a*'a)set" "('a*'a)set\<Rightarrow>nat\<Rightarrow>('a*'a)set"}\\
\end{tabular}
\subsubsection*{Syntax}
@@ -318,7 +319,6 @@
@{term "op + :: nat \<Rightarrow> nat \<Rightarrow> nat"} &
@{term "op - :: nat \<Rightarrow> nat \<Rightarrow> nat"} &
@{term "op * :: nat \<Rightarrow> nat \<Rightarrow> nat"} &
-@{term "op ^ :: nat \<Rightarrow> nat \<Rightarrow> nat"} &
@{term "op div :: nat \<Rightarrow> nat \<Rightarrow> nat"}&
@{term "op mod :: nat \<Rightarrow> nat \<Rightarrow> nat"}&
@{term "op dvd :: nat \<Rightarrow> nat \<Rightarrow> bool"}\\
@@ -331,7 +331,9 @@
\end{tabular}
\begin{tabular}{@ {} l @ {~::~} l @ {}}
-@{const Nat.of_nat} & @{typeof Nat.of_nat}
+@{const Nat.of_nat} & @{typeof Nat.of_nat}\\
+@{term "op ^^ :: ('a \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> 'a"} &
+ @{term_type_only "op ^^ :: ('a \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> 'a" "('a \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> 'a"}
\end{tabular}
\section{Int}
@@ -450,14 +452,6 @@
\end{tabular}
-\section{Iterated Functions and Relations}
-
-Theory: @{theory Relation_Power}
-
-Iterated functions \ @{term[source]"(f::'a\<Rightarrow>'a) ^ n"} \
-and relations \ @{term[source]"(r::('a\<times>'a)set) ^ n"}.
-
-
\section{Option}
@{datatype option}
--- a/doc-src/Main/Docs/document/Main_Doc.tex Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/Main/Docs/document/Main_Doc.tex Mon May 11 17:20:52 2009 +0200
@@ -279,6 +279,7 @@
\isa{rtrancl} & \isa{{\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set}\\
\isa{trancl} & \isa{{\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set}\\
\isa{reflcl} & \isa{{\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set}\\
+\isa{op\ {\isacharcircum}{\isacharcircum}} & \isa{{\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set}\\
\end{tabular}
\subsubsection*{Syntax}
@@ -328,7 +329,6 @@
\isa{op\ {\isacharplus}} &
\isa{op\ {\isacharminus}} &
\isa{op\ {\isacharasterisk}} &
-\isa{op\ {\isacharcircum}} &
\isa{op\ div}&
\isa{op\ mod}&
\isa{op\ dvd}\\
@@ -341,7 +341,9 @@
\end{tabular}
\begin{tabular}{@ {} l @ {~::~} l @ {}}
-\isa{of{\isacharunderscore}nat} & \isa{nat\ {\isasymRightarrow}\ {\isacharprime}a}
+\isa{of{\isacharunderscore}nat} & \isa{nat\ {\isasymRightarrow}\ {\isacharprime}a}\\
+\isa{op\ {\isacharcircum}{\isacharcircum}} &
+ \isa{{\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isacharparenright}\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a}
\end{tabular}
\section{Int}
@@ -460,14 +462,6 @@
\end{tabular}
-\section{Iterated Functions and Relations}
-
-Theory: \isa{Relation{\isacharunderscore}Power}
-
-Iterated functions \ \isa{{\isachardoublequote}{\isacharparenleft}f{\isacharcolon}{\isacharcolon}{\isacharprime}a{\isasymRightarrow}{\isacharprime}a{\isacharparenright}\ {\isacharcircum}\ n{\isachardoublequote}} \
-and relations \ \isa{{\isachardoublequote}{\isacharparenleft}r{\isacharcolon}{\isacharcolon}{\isacharparenleft}{\isacharprime}a{\isasymtimes}{\isacharprime}a{\isacharparenright}set{\isacharparenright}\ {\isacharcircum}\ n{\isachardoublequote}}.
-
-
\section{Option}
\isa{\isacommand{datatype}\ {\isacharprime}a\ option\ {\isacharequal}\ None\ {\isacharbar}\ Some\ {\isacharprime}a}
--- a/doc-src/TutorialI/tutorial.tex Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/TutorialI/tutorial.tex Mon May 11 17:20:52 2009 +0200
@@ -39,10 +39,11 @@
%University of Cambridge\\
%Computer Laboratory
}
+\pagenumbering{roman}
\maketitle
+\newpage
-\pagenumbering{roman}
-\setcounter{page}{5}
+%\setcounter{page}{5}
%\vspace*{\fill}
%\begin{center}
%\LARGE In memoriam \\[1ex]
@@ -52,6 +53,7 @@
%\vspace*{\fill}
%\vspace*{\fill}
%\newpage
+
\include{preface}
\tableofcontents
--- a/doc-src/more_antiquote.ML Mon May 11 09:39:53 2009 +0200
+++ b/doc-src/more_antiquote.ML Mon May 11 17:20:52 2009 +0200
@@ -88,7 +88,7 @@
let
val thy = ProofContext.theory_of ctxt;
val const = Code_Unit.check_const thy raw_const;
- val (_, funcgr) = Code_Wellsorted.make thy [const];
+ val (_, funcgr) = Code_Wellsorted.obtain thy [const] [];
fun holize thm = @{thm meta_eq_to_obj_eq} OF [thm];
val thms = Code_Wellsorted.eqns funcgr const
|> map_filter (fn (thm, linear) => if linear then SOME thm else NONE)
--- a/etc/isar-keywords.el Mon May 11 09:39:53 2009 +0200
+++ b/etc/isar-keywords.el Mon May 11 17:20:52 2009 +0200
@@ -35,6 +35,7 @@
"atp_info"
"atp_kill"
"atp_messages"
+ "atp_minimize"
"attribute_setup"
"automaton"
"ax_specification"
@@ -340,6 +341,7 @@
"atp_info"
"atp_kill"
"atp_messages"
+ "atp_minimize"
"cd"
"class_deps"
"code_deps"
--- a/lib/jedit/isabelle.xml Mon May 11 09:39:53 2009 +0200
+++ b/lib/jedit/isabelle.xml Mon May 11 17:20:52 2009 +0200
@@ -60,6 +60,7 @@
<LABEL>atp_info</LABEL>
<LABEL>atp_kill</LABEL>
<LABEL>atp_messages</LABEL>
+ <LABEL>atp_minimize</LABEL>
<KEYWORD4>attach</KEYWORD4>
<OPERATOR>attribute_setup</OPERATOR>
<OPERATOR>automaton</OPERATOR>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/scripts/SystemOnTPTP Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,120 @@
+#!/usr/bin/env perl
+#
+# Wrapper for custom remote provers on SystemOnTPTP
+# Author: Fabian Immler, TU Muenchen
+#
+
+use warnings;
+use strict;
+use Getopt::Std;
+use HTTP::Request::Common;
+use LWP;
+
+my $SystemOnTPTPFormReplyURL = "http://www.cs.miami.edu/~tptp/cgi-bin/SystemOnTPTPFormReply";
+
+# default parameters
+my %URLParameters = (
+ "NoHTML" => 1,
+ "QuietFlag" => "-q01",
+ "X2TPTP" => "-S",
+ "SubmitButton" => "RunSelectedSystems",
+ "ProblemSource" => "UPLOAD",
+ );
+
+#----Get format and transform options if specified
+my %Options;
+getopts("hws:t:c:",\%Options);
+
+#----Usage
+sub usage() {
+ print("Usage: remote [<options>] <File name>\n");
+ print(" <options> are ...\n");
+ print(" -h - print this help\n");
+ print(" -w - list available ATP systems\n");
+ print(" -s<system> - specified system to use\n");
+ print(" -t<timelimit> - CPU time limit for system\n");
+ print(" -c<command> - custom command for system\n");
+ print(" <File name> - TPTP problem file\n");
+ exit(0);
+}
+if (exists($Options{'h'})) {
+ usage();
+}
+#----What systems flag
+if (exists($Options{'w'})) {
+ $URLParameters{"SubmitButton"} = "ListSystems";
+ delete($URLParameters{"ProblemSource"});
+}
+#----Selected system
+my $System;
+if (exists($Options{'s'})) {
+ $System = $Options{'s'};
+} else {
+ # use Vampire as default
+ $System = "Vampire---9.0";
+}
+$URLParameters{"System___$System"} = $System;
+
+#----Time limit
+if (exists($Options{'t'})) {
+ $URLParameters{"TimeLimit___$System"} = $Options{'t'};
+}
+#----Custom command
+if (exists($Options{'c'})) {
+ $URLParameters{"Command___$System"} = $Options{'c'};
+}
+
+#----Get single file name
+if (exists($URLParameters{"ProblemSource"})) {
+ if (scalar(@ARGV) >= 1) {
+ $URLParameters{"UPLOADProblem"} = [shift(@ARGV)];
+ } else {
+ print("Missing problem file\n");
+ usage();
+ die;
+ }
+}
+
+# Query Server
+my $Agent = LWP::UserAgent->new;
+if (exists($Options{'t'})) {
+ # give server more time to respond
+ $Agent->timeout($Options{'t'} + 10);
+}
+my $Request = POST($SystemOnTPTPFormReplyURL,
+ Content_Type => 'form-data',Content => \%URLParameters);
+my $Response = $Agent->request($Request);
+
+#catch errors / failure
+if(! $Response->is_success){
+ print "HTTP-Error: " . $Response->message . "\n";
+ exit(-1);
+} elsif (exists($Options{'w'})) {
+ print $Response->content;
+ exit (0);
+} elsif ($Response->content =~ /WARNING: (\S*) does not exist/) {
+ print "Specified System $1 does not exist\n";
+ exit(-1);
+} elsif ($Response->content =~ /%\s*Result\s*:\s*Unsatisfiable.*\n%\s*Output\s*:\s*(CNF)?Refutation.*\n%/) {
+ my @lines = split( /\n/, $Response->content);
+ my $extract = "";
+ foreach my $line (@lines){
+ #ignore comments
+ if ($line !~ /^%/ && !($line eq "")) {
+ $extract .= "$line";
+ }
+ }
+ # insert newlines after ').'
+ $extract =~ s/\s//g;
+ $extract =~ s/\)\.cnf/\)\.\ncnf/g;
+
+ # orientation for res_reconstruct.ML
+ print "# SZS output start CNFRefutation.\n";
+ print "$extract\n";
+ print "# SZS output end CNFRefutation.\n";
+ exit(0);
+} else {
+ print "Remote-script could not extract proof:\n".$Response->content;
+ exit(-1);
+}
+
--- a/src/HOL/ATP_Linkup.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ATP_Linkup.thy Mon May 11 17:20:52 2009 +0200
@@ -17,6 +17,7 @@
("Tools/res_atp.ML")
("Tools/atp_manager.ML")
("Tools/atp_wrapper.ML")
+ ("Tools/atp_minimal.ML")
"~~/src/Tools/Metis/metis.ML"
("Tools/metis_tools.ML")
begin
@@ -98,6 +99,8 @@
use "Tools/atp_manager.ML"
use "Tools/atp_wrapper.ML"
+use "Tools/atp_minimal.ML"
+
text {* basic provers *}
setup {* AtpManager.add_prover "spass" AtpWrapper.spass *}
setup {* AtpManager.add_prover "vampire" AtpWrapper.vampire *}
--- a/src/HOL/Algebra/abstract/Ring2.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Algebra/abstract/Ring2.thy Mon May 11 17:20:52 2009 +0200
@@ -12,7 +12,7 @@
subsection {* Ring axioms *}
-class ring = zero + one + plus + minus + uminus + times + inverse + power + Ring_and_Field.dvd +
+class ring = zero + one + plus + minus + uminus + times + inverse + power + dvd +
assumes a_assoc: "(a + b) + c = a + (b + c)"
and l_zero: "0 + a = a"
and l_neg: "(-a) + a = 0"
@@ -28,8 +28,6 @@
assumes minus_def: "a - b = a + (-b)"
and inverse_def: "inverse a = (if a dvd 1 then THE x. a*x = 1 else 0)"
and divide_def: "a / b = a * inverse b"
- and power_0 [simp]: "a ^ 0 = 1"
- and power_Suc [simp]: "a ^ Suc n = a ^ n * a"
begin
definition assoc :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infixl "assoc" 50) where
--- a/src/HOL/Algebra/poly/LongDiv.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Algebra/poly/LongDiv.thy Mon May 11 17:20:52 2009 +0200
@@ -1,6 +1,5 @@
(*
Experimental theory: long division of polynomials
- $Id$
Author: Clemens Ballarin, started 23 June 1999
*)
@@ -133,9 +132,9 @@
delsimprocs [ring_simproc]) 1 *})
apply (tactic {* asm_simp_tac (@{simpset} delsimprocs [ring_simproc]) 1 *})
apply (tactic {* simp_tac (@{simpset} addsimps [thm "minus_def", thm "smult_r_distr",
- thm "smult_r_minus", thm "monom_mult_smult", thm "smult_assoc1", thm "smult_assoc2"]
+ thm "smult_r_minus", thm "monom_mult_smult", thm "smult_assoc2"]
delsimprocs [ring_simproc]) 1 *})
- apply simp
+ apply (simp add: smult_assoc1 [symmetric])
done
ML {*
--- a/src/HOL/Algebra/poly/UnivPoly2.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Algebra/poly/UnivPoly2.thy Mon May 11 17:20:52 2009 +0200
@@ -155,16 +155,6 @@
end
-instantiation up :: ("{times, one, comm_monoid_add}") power
-begin
-
-primrec power_up where
- "(a \<Colon> 'a up) ^ 0 = 1"
- | "(a \<Colon> 'a up) ^ Suc n = a ^ n * a"
-
-instance ..
-
-end
subsection {* Effect of operations on coefficients *}
@@ -328,8 +318,9 @@
qed
show "(p + q) * r = p * r + q * r"
by (rule up_eqI) simp
- show "p * q = q * p"
+ show "\<And>q. p * q = q * p"
proof (rule up_eqI)
+ fix q
fix n
{
fix k
@@ -354,9 +345,6 @@
by (simp add: up_inverse_def)
show "p / q = p * inverse q"
by (simp add: up_divide_def)
- fix n
- show "p ^ 0 = 1" by simp
- show "p ^ Suc n = p ^ n * p" by simp
qed
(* Further properties of monom *)
--- a/src/HOL/Bali/Trans.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Bali/Trans.thy Mon May 11 17:20:52 2009 +0200
@@ -359,7 +359,7 @@
abbreviation
stepn:: "[prog, term \<times> state,nat,term \<times> state] \<Rightarrow> bool" ("_\<turnstile>_ \<mapsto>_ _"[61,82,82] 81)
- where "G\<turnstile>p \<mapsto>n p' \<equiv> (p,p') \<in> {(x, y). step G x y}^n"
+ where "G\<turnstile>p \<mapsto>n p' \<equiv> (p,p') \<in> {(x, y). step G x y}^^n"
abbreviation
steptr:: "[prog,term \<times> state,term \<times> state] \<Rightarrow> bool" ("_\<turnstile>_ \<mapsto>* _"[61,82,82] 81)
@@ -370,25 +370,6 @@
Smallstep zu Bigstep, nur wenn nicht die Ausdrücke Callee, FinA ,\<dots>
*)
-lemma rtrancl_imp_rel_pow: "p \<in> R^* \<Longrightarrow> \<exists>n. p \<in> R^n"
-proof -
- assume "p \<in> R\<^sup>*"
- moreover obtain x y where p: "p = (x,y)" by (cases p)
- ultimately have "(x,y) \<in> R\<^sup>*" by hypsubst
- hence "\<exists>n. (x,y) \<in> R^n"
- proof induct
- fix a have "(a,a) \<in> R^0" by simp
- thus "\<exists>n. (a,a) \<in> R ^ n" ..
- next
- fix a b c assume "\<exists>n. (a,b) \<in> R ^ n"
- then obtain n where "(a,b) \<in> R^n" ..
- moreover assume "(b,c) \<in> R"
- ultimately have "(a,c) \<in> R^(Suc n)" by auto
- thus "\<exists>n. (a,c) \<in> R^n" ..
- qed
- with p show ?thesis by hypsubst
-qed
-
(*
lemma imp_eval_trans:
assumes eval: "G\<turnstile>s0 \<midarrow>t\<succ>\<rightarrow> (v,s1)"
--- a/src/HOL/Code_Eval.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Code_Eval.thy Mon May 11 17:20:52 2009 +0200
@@ -23,7 +23,7 @@
code_datatype Const App
class term_of = typerep +
- fixes term_of :: "'a::{} \<Rightarrow> term"
+ fixes term_of :: "'a \<Rightarrow> term"
lemma term_of_anything: "term_of x \<equiv> t"
by (rule eq_reflection) (cases "term_of x", cases t, simp)
@@ -33,7 +33,7 @@
struct
fun mk_term f g (Const (c, ty)) =
- @{term Const} $ Message_String.mk c $ g ty
+ @{term Const} $ HOLogic.mk_message_string c $ g ty
| mk_term f g (t1 $ t2) =
@{term App} $ mk_term f g t1 $ mk_term f g t2
| mk_term f g (Free v) = f v
@@ -67,18 +67,19 @@
|> Class.prove_instantiation_instance (K (Class.intro_classes_tac []))
|> LocalTheory.exit_global
end;
- fun interpretator (tyco, (raw_vs, _)) thy =
- let
- val has_inst = can (Sorts.mg_domain (Sign.classes_of thy) tyco) @{sort term_of};
- val constrain_sort =
- curry (Sorts.inter_sort (Sign.classes_of thy)) @{sort term_of};
- val vs = (map o apsnd) constrain_sort raw_vs;
- val ty = Type (tyco, map TFree vs);
- in
- thy
- |> Typerep.perhaps_add_def tyco
- |> not has_inst ? add_term_of_def ty vs tyco
- end;
+ fun interpretator ("prop", (raw_vs, _)) thy = thy
+ | interpretator (tyco, (raw_vs, _)) thy =
+ let
+ val has_inst = can (Sorts.mg_domain (Sign.classes_of thy) tyco) @{sort term_of};
+ val constrain_sort =
+ curry (Sorts.inter_sort (Sign.classes_of thy)) @{sort term_of};
+ val vs = (map o apsnd) constrain_sort raw_vs;
+ val ty = Type (tyco, map TFree vs);
+ in
+ thy
+ |> Typerep.perhaps_add_def tyco
+ |> not has_inst ? add_term_of_def ty vs tyco
+ end;
in
Code.type_interpretation interpretator
end
@@ -105,21 +106,22 @@
thy
|> Code.add_eqn thm
end;
- fun interpretator (tyco, (raw_vs, raw_cs)) thy =
- let
- val constrain_sort =
- curry (Sorts.inter_sort (Sign.classes_of thy)) @{sort term_of};
- val vs = (map o apsnd) constrain_sort raw_vs;
- val cs = (map o apsnd o map o map_atyps)
- (fn TFree (v, sort) => TFree (v, constrain_sort sort)) raw_cs;
- val ty = Type (tyco, map TFree vs);
- val eqs = map (mk_term_of_eq ty vs tyco) cs;
- val const = AxClass.param_of_inst thy (@{const_name term_of}, tyco);
- in
- thy
- |> Code.del_eqns const
- |> fold (prove_term_of_eq ty) eqs
- end;
+ fun interpretator ("prop", (raw_vs, _)) thy = thy
+ | interpretator (tyco, (raw_vs, raw_cs)) thy =
+ let
+ val constrain_sort =
+ curry (Sorts.inter_sort (Sign.classes_of thy)) @{sort term_of};
+ val vs = (map o apsnd) constrain_sort raw_vs;
+ val cs = (map o apsnd o map o map_atyps)
+ (fn TFree (v, sort) => TFree (v, constrain_sort sort)) raw_cs;
+ val ty = Type (tyco, map TFree vs);
+ val eqs = map (mk_term_of_eq ty vs tyco) cs;
+ val const = AxClass.param_of_inst thy (@{const_name term_of}, tyco);
+ in
+ thy
+ |> Code.del_eqns const
+ |> fold (prove_term_of_eq ty) eqs
+ end;
in
Code.type_interpretation interpretator
end
@@ -146,13 +148,15 @@
by (subst term_of_anything) rule
code_type "term"
- (SML "Term.term")
+ (Eval "Term.term")
code_const Const and App
- (SML "Term.Const/ (_, _)" and "Term.$/ (_, _)")
+ (Eval "Term.Const/ (_, _)" and "Term.$/ (_, _)")
code_const "term_of \<Colon> message_string \<Rightarrow> term"
- (SML "Message'_String.mk")
+ (Eval "HOLogic.mk'_message'_string")
+
+code_reserved Eval HOLogic
subsection {* Evaluation setup *}
@@ -161,6 +165,7 @@
signature EVAL =
sig
val mk_term: ((string * typ) -> term) -> (typ -> term) -> term -> term
+ val mk_term_of: typ -> term -> term
val eval_ref: (unit -> term) option ref
val eval_term: theory -> term -> term
end;
@@ -175,8 +180,7 @@
fun eval_term thy t =
t
|> Eval.mk_term_of (fastype_of t)
- |> (fn t => Code_ML.eval_term ("Eval.eval_ref", eval_ref) thy t [])
- |> Code.postprocess_term thy;
+ |> (fn t => Code_ML.eval NONE ("Eval.eval_ref", eval_ref) I thy t []);
end;
*}
--- a/src/HOL/Code_Message.thy Mon May 11 09:39:53 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-(* ID: $Id$
- Author: Florian Haftmann, TU Muenchen
-*)
-
-header {* Monolithic strings (message strings) for code generation *}
-
-theory Code_Message
-imports Plain "~~/src/HOL/List"
-begin
-
-subsection {* Datatype of messages *}
-
-datatype message_string = STR string
-
-lemmas [code del] = message_string.recs message_string.cases
-
-lemma [code]: "size (s\<Colon>message_string) = 0"
- by (cases s) simp_all
-
-lemma [code]: "message_string_size (s\<Colon>message_string) = 0"
- by (cases s) simp_all
-
-subsection {* ML interface *}
-
-ML {*
-structure Message_String =
-struct
-
-fun mk s = @{term STR} $ HOLogic.mk_string s;
-
-end;
-*}
-
-
-subsection {* Code serialization *}
-
-code_type message_string
- (SML "string")
- (OCaml "string")
- (Haskell "String")
-
-setup {*
- fold (fn target => add_literal_message @{const_name STR} target)
- ["SML", "OCaml", "Haskell"]
-*}
-
-code_reserved SML string
-code_reserved OCaml string
-
-code_instance message_string :: eq
- (Haskell -)
-
-code_const "eq_class.eq \<Colon> message_string \<Rightarrow> message_string \<Rightarrow> bool"
- (SML "!((_ : string) = _)")
- (OCaml "!((_ : string) = _)")
- (Haskell infixl 4 "==")
-
-end
--- a/src/HOL/Code_Setup.thy Mon May 11 09:39:53 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,253 +0,0 @@
-(* Title: HOL/Code_Setup.thy
- ID: $Id$
- Author: Florian Haftmann
-*)
-
-header {* Setup of code generators and related tools *}
-
-theory Code_Setup
-imports HOL
-begin
-
-subsection {* Generic code generator foundation *}
-
-text {* Datatypes *}
-
-code_datatype True False
-
-code_datatype "TYPE('a\<Colon>{})"
-
-code_datatype Trueprop "prop"
-
-text {* Code equations *}
-
-lemma [code]:
- shows "(True \<Longrightarrow> PROP P) \<equiv> PROP P"
- and "(False \<Longrightarrow> Q) \<equiv> Trueprop True"
- and "(PROP P \<Longrightarrow> True) \<equiv> Trueprop True"
- and "(Q \<Longrightarrow> False) \<equiv> Trueprop (\<not> Q)" by (auto intro!: equal_intr_rule)
-
-lemma [code]:
- shows "False \<and> x \<longleftrightarrow> False"
- and "True \<and> x \<longleftrightarrow> x"
- and "x \<and> False \<longleftrightarrow> False"
- and "x \<and> True \<longleftrightarrow> x" by simp_all
-
-lemma [code]:
- shows "False \<or> x \<longleftrightarrow> x"
- and "True \<or> x \<longleftrightarrow> True"
- and "x \<or> False \<longleftrightarrow> x"
- and "x \<or> True \<longleftrightarrow> True" by simp_all
-
-lemma [code]:
- shows "\<not> True \<longleftrightarrow> False"
- and "\<not> False \<longleftrightarrow> True" by (rule HOL.simp_thms)+
-
-lemmas [code] = Let_def if_True if_False
-
-lemmas [code, code unfold, symmetric, code post] = imp_conv_disj
-
-text {* Equality *}
-
-context eq
-begin
-
-lemma equals_eq [code inline, code]: "op = \<equiv> eq"
- by (rule eq_reflection) (rule ext, rule ext, rule sym, rule eq_equals)
-
-declare eq [code unfold, code inline del]
-
-declare equals_eq [symmetric, code post]
-
-end
-
-declare simp_thms(6) [code nbe]
-
-hide (open) const eq
-hide const eq
-
-setup {*
- Code_Unit.add_const_alias @{thm equals_eq}
-*}
-
-text {* Cases *}
-
-lemma Let_case_cert:
- assumes "CASE \<equiv> (\<lambda>x. Let x f)"
- shows "CASE x \<equiv> f x"
- using assms by simp_all
-
-lemma If_case_cert:
- assumes "CASE \<equiv> (\<lambda>b. If b f g)"
- shows "(CASE True \<equiv> f) &&& (CASE False \<equiv> g)"
- using assms by simp_all
-
-setup {*
- Code.add_case @{thm Let_case_cert}
- #> Code.add_case @{thm If_case_cert}
- #> Code.add_undefined @{const_name undefined}
-*}
-
-code_abort undefined
-
-
-subsection {* Generic code generator preprocessor *}
-
-setup {*
- Code.map_pre (K HOL_basic_ss)
- #> Code.map_post (K HOL_basic_ss)
-*}
-
-
-subsection {* Generic code generator target languages *}
-
-text {* type bool *}
-
-code_type bool
- (SML "bool")
- (OCaml "bool")
- (Haskell "Bool")
-
-code_const True and False and Not and "op &" and "op |" and If
- (SML "true" and "false" and "not"
- and infixl 1 "andalso" and infixl 0 "orelse"
- and "!(if (_)/ then (_)/ else (_))")
- (OCaml "true" and "false" and "not"
- and infixl 4 "&&" and infixl 2 "||"
- and "!(if (_)/ then (_)/ else (_))")
- (Haskell "True" and "False" and "not"
- and infixl 3 "&&" and infixl 2 "||"
- and "!(if (_)/ then (_)/ else (_))")
-
-code_reserved SML
- bool true false not
-
-code_reserved OCaml
- bool not
-
-text {* using built-in Haskell equality *}
-
-code_class eq
- (Haskell "Eq")
-
-code_const "eq_class.eq"
- (Haskell infixl 4 "==")
-
-code_const "op ="
- (Haskell infixl 4 "==")
-
-text {* undefined *}
-
-code_const undefined
- (SML "!(raise/ Fail/ \"undefined\")")
- (OCaml "failwith/ \"undefined\"")
- (Haskell "error/ \"undefined\"")
-
-
-subsection {* SML code generator setup *}
-
-types_code
- "bool" ("bool")
-attach (term_of) {*
-fun term_of_bool b = if b then HOLogic.true_const else HOLogic.false_const;
-*}
-attach (test) {*
-fun gen_bool i =
- let val b = one_of [false, true]
- in (b, fn () => term_of_bool b) end;
-*}
- "prop" ("bool")
-attach (term_of) {*
-fun term_of_prop b =
- HOLogic.mk_Trueprop (if b then HOLogic.true_const else HOLogic.false_const);
-*}
-
-consts_code
- "Trueprop" ("(_)")
- "True" ("true")
- "False" ("false")
- "Not" ("Bool.not")
- "op |" ("(_ orelse/ _)")
- "op &" ("(_ andalso/ _)")
- "If" ("(if _/ then _/ else _)")
-
-setup {*
-let
-
-fun eq_codegen thy defs dep thyname b t gr =
- (case strip_comb t of
- (Const ("op =", Type (_, [Type ("fun", _), _])), _) => NONE
- | (Const ("op =", _), [t, u]) =>
- let
- val (pt, gr') = Codegen.invoke_codegen thy defs dep thyname false t gr;
- val (pu, gr'') = Codegen.invoke_codegen thy defs dep thyname false u gr';
- val (_, gr''') = Codegen.invoke_tycodegen thy defs dep thyname false HOLogic.boolT gr'';
- in
- SOME (Codegen.parens
- (Pretty.block [pt, Codegen.str " =", Pretty.brk 1, pu]), gr''')
- end
- | (t as Const ("op =", _), ts) => SOME (Codegen.invoke_codegen
- thy defs dep thyname b (Codegen.eta_expand t ts 2) gr)
- | _ => NONE);
-
-in
- Codegen.add_codegen "eq_codegen" eq_codegen
-end
-*}
-
-
-subsection {* Evaluation and normalization by evaluation *}
-
-setup {*
- Value.add_evaluator ("SML", Codegen.eval_term o ProofContext.theory_of)
-*}
-
-ML {*
-structure Eval_Method =
-struct
-
-val eval_ref : (unit -> bool) option ref = ref NONE;
-
-end;
-*}
-
-oracle eval_oracle = {* fn ct =>
- let
- val thy = Thm.theory_of_cterm ct;
- val t = Thm.term_of ct;
- val dummy = @{cprop True};
- in case try HOLogic.dest_Trueprop t
- of SOME t' => if Code_ML.eval_term
- ("Eval_Method.eval_ref", Eval_Method.eval_ref) thy t' []
- then Thm.capply (Thm.capply @{cterm "op \<equiv> \<Colon> prop \<Rightarrow> prop \<Rightarrow> prop"} ct) dummy
- else dummy
- | NONE => dummy
- end
-*}
-
-ML {*
-fun gen_eval_method conv ctxt = SIMPLE_METHOD'
- (CONVERSION (Conv.params_conv (~1) (K (Conv.concl_conv (~1) conv)) ctxt)
- THEN' rtac TrueI)
-*}
-
-method_setup eval = {* Scan.succeed (gen_eval_method eval_oracle) *}
- "solve goal by evaluation"
-
-method_setup evaluation = {* Scan.succeed (gen_eval_method Codegen.evaluation_conv) *}
- "solve goal by evaluation"
-
-method_setup normalization = {*
- Scan.succeed (K (SIMPLE_METHOD' (CONVERSION Nbe.norm_conv THEN' (fn k => TRY (rtac TrueI k)))))
-*} "solve goal by normalization"
-
-
-subsection {* Quickcheck *}
-
-setup {*
- Quickcheck.add_generator ("SML", Codegen.test_term)
-*}
-
-quickcheck_params [size = 5, iterations = 50]
-
-end
--- a/src/HOL/Complex.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Complex.thy Mon May 11 17:20:52 2009 +0200
@@ -157,23 +157,6 @@
end
-subsection {* Exponentiation *}
-
-instantiation complex :: recpower
-begin
-
-primrec power_complex where
- "z ^ 0 = (1\<Colon>complex)"
-| "z ^ Suc n = (z\<Colon>complex) * z ^ n"
-
-instance proof
-qed simp_all
-
-declare power_complex.simps [simp del]
-
-end
-
-
subsection {* Numerals and Arithmetic *}
instantiation complex :: number_ring
--- a/src/HOL/Decision_Procs/Approximation.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Decision_Procs/Approximation.thy Mon May 11 17:20:52 2009 +0200
@@ -23,8 +23,8 @@
qed
lemma horner_schema: fixes f :: "nat \<Rightarrow> nat" and G :: "nat \<Rightarrow> nat \<Rightarrow> nat" and F :: "nat \<Rightarrow> nat"
- assumes f_Suc: "\<And>n. f (Suc n) = G ((F^n) s) (f n)"
- shows "horner F G n ((F^j') s) (f j') x = (\<Sum> j = 0..< n. -1^j * (1 / real (f (j' + j))) * x^j)"
+ assumes f_Suc: "\<And>n. f (Suc n) = G ((F ^^ n) s) (f n)"
+ shows "horner F G n ((F ^^ j') s) (f j') x = (\<Sum> j = 0..< n. -1 ^ j * (1 / real (f (j' + j))) * x ^ j)"
proof (induct n arbitrary: i k j')
case (Suc n)
@@ -33,13 +33,13 @@
qed auto
lemma horner_bounds':
- assumes "0 \<le> Ifloat x" and f_Suc: "\<And>n. f (Suc n) = G ((F^n) s) (f n)"
+ assumes "0 \<le> Ifloat x" and f_Suc: "\<And>n. f (Suc n) = G ((F ^^ n) s) (f n)"
and lb_0: "\<And> i k x. lb 0 i k x = 0"
and lb_Suc: "\<And> n i k x. lb (Suc n) i k x = lapprox_rat prec 1 (int k) - x * (ub n (F i) (G i k) x)"
and ub_0: "\<And> i k x. ub 0 i k x = 0"
and ub_Suc: "\<And> n i k x. ub (Suc n) i k x = rapprox_rat prec 1 (int k) - x * (lb n (F i) (G i k) x)"
- shows "Ifloat (lb n ((F^j') s) (f j') x) \<le> horner F G n ((F^j') s) (f j') (Ifloat x) \<and>
- horner F G n ((F^j') s) (f j') (Ifloat x) \<le> Ifloat (ub n ((F^j') s) (f j') x)"
+ shows "Ifloat (lb n ((F ^^ j') s) (f j') x) \<le> horner F G n ((F ^^ j') s) (f j') (Ifloat x) \<and>
+ horner F G n ((F ^^ j') s) (f j') (Ifloat x) \<le> Ifloat (ub n ((F ^^ j') s) (f j') x)"
(is "?lb n j' \<le> ?horner n j' \<and> ?horner n j' \<le> ?ub n j'")
proof (induct n arbitrary: j')
case 0 thus ?case unfolding lb_0 ub_0 horner.simps by auto
@@ -49,15 +49,15 @@
proof (rule add_mono)
show "Ifloat (lapprox_rat prec 1 (int (f j'))) \<le> 1 / real (f j')" using lapprox_rat[of prec 1 "int (f j')"] by auto
from Suc[where j'="Suc j'", unfolded funpow.simps comp_def f_Suc, THEN conjunct2] `0 \<le> Ifloat x`
- show "- Ifloat (x * ub n (F ((F ^ j') s)) (G ((F ^ j') s) (f j')) x) \<le> - (Ifloat x * horner F G n (F ((F ^ j') s)) (G ((F ^ j') s) (f j')) (Ifloat x))"
+ show "- Ifloat (x * ub n (F ((F ^^ j') s)) (G ((F ^^ j') s) (f j')) x) \<le> - (Ifloat x * horner F G n (F ((F ^^ j') s)) (G ((F ^^ j') s) (f j')) (Ifloat x))"
unfolding Ifloat_mult neg_le_iff_le by (rule mult_left_mono)
qed
moreover have "?horner (Suc n) j' \<le> ?ub (Suc n) j'" unfolding ub_Suc ub_Suc horner.simps Ifloat_sub diff_def
proof (rule add_mono)
show "1 / real (f j') \<le> Ifloat (rapprox_rat prec 1 (int (f j')))" using rapprox_rat[of 1 "int (f j')" prec] by auto
from Suc[where j'="Suc j'", unfolded funpow.simps comp_def f_Suc, THEN conjunct1] `0 \<le> Ifloat x`
- show "- (Ifloat x * horner F G n (F ((F ^ j') s)) (G ((F ^ j') s) (f j')) (Ifloat x)) \<le>
- - Ifloat (x * lb n (F ((F ^ j') s)) (G ((F ^ j') s) (f j')) x)"
+ show "- (Ifloat x * horner F G n (F ((F ^^ j') s)) (G ((F ^^ j') s) (f j')) (Ifloat x)) \<le>
+ - Ifloat (x * lb n (F ((F ^^ j') s)) (G ((F ^^ j') s) (f j')) x)"
unfolding Ifloat_mult neg_le_iff_le by (rule mult_left_mono)
qed
ultimately show ?case by blast
@@ -73,13 +73,13 @@
*}
lemma horner_bounds: fixes F :: "nat \<Rightarrow> nat" and G :: "nat \<Rightarrow> nat \<Rightarrow> nat"
- assumes "0 \<le> Ifloat x" and f_Suc: "\<And>n. f (Suc n) = G ((F^n) s) (f n)"
+ assumes "0 \<le> Ifloat x" and f_Suc: "\<And>n. f (Suc n) = G ((F ^^ n) s) (f n)"
and lb_0: "\<And> i k x. lb 0 i k x = 0"
and lb_Suc: "\<And> n i k x. lb (Suc n) i k x = lapprox_rat prec 1 (int k) - x * (ub n (F i) (G i k) x)"
and ub_0: "\<And> i k x. ub 0 i k x = 0"
and ub_Suc: "\<And> n i k x. ub (Suc n) i k x = rapprox_rat prec 1 (int k) - x * (lb n (F i) (G i k) x)"
- shows "Ifloat (lb n ((F^j') s) (f j') x) \<le> (\<Sum>j=0..<n. -1^j * (1 / real (f (j' + j))) * (Ifloat x)^j)" (is "?lb") and
- "(\<Sum>j=0..<n. -1^j * (1 / real (f (j' + j))) * (Ifloat x)^j) \<le> Ifloat (ub n ((F^j') s) (f j') x)" (is "?ub")
+ shows "Ifloat (lb n ((F ^^ j') s) (f j') x) \<le> (\<Sum>j=0..<n. -1 ^ j * (1 / real (f (j' + j))) * Ifloat x ^ j)" (is "?lb") and
+ "(\<Sum>j=0..<n. -1 ^ j * (1 / real (f (j' + j))) * (Ifloat x ^ j)) \<le> Ifloat (ub n ((F ^^ j') s) (f j') x)" (is "?ub")
proof -
have "?lb \<and> ?ub"
using horner_bounds'[where lb=lb, OF `0 \<le> Ifloat x` f_Suc lb_0 lb_Suc ub_0 ub_Suc]
@@ -88,29 +88,29 @@
qed
lemma horner_bounds_nonpos: fixes F :: "nat \<Rightarrow> nat" and G :: "nat \<Rightarrow> nat \<Rightarrow> nat"
- assumes "Ifloat x \<le> 0" and f_Suc: "\<And>n. f (Suc n) = G ((F^n) s) (f n)"
+ assumes "Ifloat x \<le> 0" and f_Suc: "\<And>n. f (Suc n) = G ((F ^^ n) s) (f n)"
and lb_0: "\<And> i k x. lb 0 i k x = 0"
and lb_Suc: "\<And> n i k x. lb (Suc n) i k x = lapprox_rat prec 1 (int k) + x * (ub n (F i) (G i k) x)"
and ub_0: "\<And> i k x. ub 0 i k x = 0"
and ub_Suc: "\<And> n i k x. ub (Suc n) i k x = rapprox_rat prec 1 (int k) + x * (lb n (F i) (G i k) x)"
- shows "Ifloat (lb n ((F^j') s) (f j') x) \<le> (\<Sum>j=0..<n. (1 / real (f (j' + j))) * (Ifloat x)^j)" (is "?lb") and
- "(\<Sum>j=0..<n. (1 / real (f (j' + j))) * (Ifloat x)^j) \<le> Ifloat (ub n ((F^j') s) (f j') x)" (is "?ub")
+ shows "Ifloat (lb n ((F ^^ j') s) (f j') x) \<le> (\<Sum>j=0..<n. (1 / real (f (j' + j))) * Ifloat x ^ j)" (is "?lb") and
+ "(\<Sum>j=0..<n. (1 / real (f (j' + j))) * (Ifloat x ^ j)) \<le> Ifloat (ub n ((F ^^ j') s) (f j') x)" (is "?ub")
proof -
{ fix x y z :: float have "x - y * z = x + - y * z"
- by (cases x, cases y, cases z, simp add: plus_float.simps minus_float.simps uminus_float.simps times_float.simps algebra_simps)
+ by (cases x, cases y, cases z, simp add: plus_float.simps minus_float_def uminus_float.simps times_float.simps algebra_simps)
} note diff_mult_minus = this
{ fix x :: float have "- (- x) = x" by (cases x, auto simp add: uminus_float.simps) } note minus_minus = this
have move_minus: "Ifloat (-x) = -1 * Ifloat x" by auto
- have sum_eq: "(\<Sum>j=0..<n. (1 / real (f (j' + j))) * (Ifloat x)^j) =
+ have sum_eq: "(\<Sum>j=0..<n. (1 / real (f (j' + j))) * Ifloat x ^ j) =
(\<Sum>j = 0..<n. -1 ^ j * (1 / real (f (j' + j))) * Ifloat (- x) ^ j)"
proof (rule setsum_cong, simp)
fix j assume "j \<in> {0 ..< n}"
show "1 / real (f (j' + j)) * Ifloat x ^ j = -1 ^ j * (1 / real (f (j' + j))) * Ifloat (- x) ^ j"
unfolding move_minus power_mult_distrib real_mult_assoc[symmetric]
- unfolding real_mult_commute unfolding real_mult_assoc[of "-1^j", symmetric] power_mult_distrib[symmetric]
+ unfolding real_mult_commute unfolding real_mult_assoc[of "-1 ^ j", symmetric] power_mult_distrib[symmetric]
by auto
qed
@@ -160,21 +160,21 @@
else (0, (max (-l) u) ^ n))"
lemma float_power_bnds: assumes "(l1, u1) = float_power_bnds n l u" and "x \<in> {Ifloat l .. Ifloat u}"
- shows "x^n \<in> {Ifloat l1..Ifloat u1}"
+ shows "x ^ n \<in> {Ifloat l1..Ifloat u1}"
proof (cases "even n")
case True
show ?thesis
proof (cases "0 < l")
case True hence "odd n \<or> 0 < l" and "0 \<le> Ifloat l" unfolding less_float_def by auto
have u1: "u1 = u ^ n" and l1: "l1 = l ^ n" using assms unfolding float_power_bnds_def if_P[OF `odd n \<or> 0 < l`] by auto
- have "Ifloat l^n \<le> x^n" and "x^n \<le> Ifloat u^n " using `0 \<le> Ifloat l` and assms unfolding atLeastAtMost_iff using power_mono[of "Ifloat l" x] power_mono[of x "Ifloat u"] by auto
+ have "Ifloat l ^ n \<le> x ^ n" and "x ^ n \<le> Ifloat u ^ n " using `0 \<le> Ifloat l` and assms unfolding atLeastAtMost_iff using power_mono[of "Ifloat l" x] power_mono[of x "Ifloat u"] by auto
thus ?thesis using assms `0 < l` unfolding atLeastAtMost_iff l1 u1 float_power less_float_def by auto
next
case False hence P: "\<not> (odd n \<or> 0 < l)" using `even n` by auto
show ?thesis
proof (cases "u < 0")
case True hence "0 \<le> - Ifloat u" and "- Ifloat u \<le> - x" and "0 \<le> - x" and "-x \<le> - Ifloat l" using assms unfolding less_float_def by auto
- hence "Ifloat u^n \<le> x^n" and "x^n \<le> Ifloat l^n" using power_mono[of "-x" "-Ifloat l" n] power_mono[of "-Ifloat u" "-x" n]
+ hence "Ifloat u ^ n \<le> x ^ n" and "x ^ n \<le> Ifloat l ^ n" using power_mono[of "-x" "-Ifloat l" n] power_mono[of "-Ifloat u" "-x" n]
unfolding power_minus_even[OF `even n`] by auto
moreover have u1: "u1 = l ^ n" and l1: "l1 = u ^ n" using assms unfolding float_power_bnds_def if_not_P[OF P] if_P[OF True] by auto
ultimately show ?thesis using float_power by auto
@@ -194,11 +194,11 @@
next
case False hence "odd n \<or> 0 < l" by auto
have u1: "u1 = u ^ n" and l1: "l1 = l ^ n" using assms unfolding float_power_bnds_def if_P[OF `odd n \<or> 0 < l`] by auto
- have "Ifloat l^n \<le> x^n" and "x^n \<le> Ifloat u^n " using assms unfolding atLeastAtMost_iff using power_mono_odd[OF False] by auto
+ have "Ifloat l ^ n \<le> x ^ n" and "x ^ n \<le> Ifloat u ^ n " using assms unfolding atLeastAtMost_iff using power_mono_odd[OF False] by auto
thus ?thesis unfolding atLeastAtMost_iff l1 u1 float_power less_float_def by auto
qed
-lemma bnds_power: "\<forall> x l u. (l1, u1) = float_power_bnds n l u \<and> x \<in> {Ifloat l .. Ifloat u} \<longrightarrow> Ifloat l1 \<le> x^n \<and> x^n \<le> Ifloat u1"
+lemma bnds_power: "\<forall> x l u. (l1, u1) = float_power_bnds n l u \<and> x \<in> {Ifloat l .. Ifloat u} \<longrightarrow> Ifloat l1 \<le> x ^ n \<and> x ^ n \<le> Ifloat u1"
using float_power_bnds by auto
section "Square root"
@@ -794,8 +794,8 @@
let "?f n" = "fact (2 * n)"
{ fix n
- have F: "\<And>m. ((\<lambda>i. i + 2) ^ n) m = m + 2 * n" by (induct n arbitrary: m, auto)
- have "?f (Suc n) = ?f n * ((\<lambda>i. i + 2) ^ n) 1 * (((\<lambda>i. i + 2) ^ n) 1 + 1)"
+ have F: "\<And>m. ((\<lambda>i. i + 2) ^^ n) m = m + 2 * n" by (induct n arbitrary: m, auto)
+ have "?f (Suc n) = ?f n * ((\<lambda>i. i + 2) ^^ n) 1 * (((\<lambda>i. i + 2) ^^ n) 1 + 1)"
unfolding F by auto } note f_eq = this
from horner_bounds[where lb="lb_sin_cos_aux prec" and ub="ub_sin_cos_aux prec" and j'=0,
@@ -811,7 +811,7 @@
have "0 < x * x" using `0 < x` unfolding less_float_def Ifloat_mult Ifloat_0
using mult_pos_pos[where a="Ifloat x" and b="Ifloat x"] by auto
- { fix x n have "(\<Sum> i=0..<n. -1^i * (1/real (fact (2 * i))) * x^(2 * i))
+ { fix x n have "(\<Sum> i=0..<n. -1^i * (1/real (fact (2 * i))) * x ^ (2 * i))
= (\<Sum> i = 0 ..< 2 * n. (if even(i) then (-1 ^ (i div 2))/(real (fact i)) else 0) * x ^ i)" (is "?sum = ?ifsum")
proof -
have "?sum = ?sum + (\<Sum> j = 0 ..< n. 0)" by auto
@@ -905,8 +905,8 @@
let "?f n" = "fact (2 * n + 1)"
{ fix n
- have F: "\<And>m. ((\<lambda>i. i + 2) ^ n) m = m + 2 * n" by (induct n arbitrary: m, auto)
- have "?f (Suc n) = ?f n * ((\<lambda>i. i + 2) ^ n) 2 * (((\<lambda>i. i + 2) ^ n) 2 + 1)"
+ have F: "\<And>m. ((\<lambda>i. i + 2) ^^ n) m = m + 2 * n" by (induct n arbitrary: m, auto)
+ have "?f (Suc n) = ?f n * ((\<lambda>i. i + 2) ^^ n) 2 * (((\<lambda>i. i + 2) ^^ n) 2 + 1)"
unfolding F by auto } note f_eq = this
from horner_bounds[where lb="lb_sin_cos_aux prec" and ub="ub_sin_cos_aux prec" and j'=0,
@@ -1382,8 +1382,8 @@
shows "exp (Ifloat x) \<in> { Ifloat (lb_exp_horner prec (get_even n) 1 1 x) .. Ifloat (ub_exp_horner prec (get_odd n) 1 1 x) }"
proof -
{ fix n
- have F: "\<And> m. ((\<lambda>i. i + 1) ^ n) m = n + m" by (induct n, auto)
- have "fact (Suc n) = fact n * ((\<lambda>i. i + 1) ^ n) 1" unfolding F by auto } note f_eq = this
+ have F: "\<And> m. ((\<lambda>i. i + 1) ^^ n) m = n + m" by (induct n, auto)
+ have "fact (Suc n) = fact n * ((\<lambda>i. i + 1) ^^ n) 1" unfolding F by auto } note f_eq = this
note bounds = horner_bounds_nonpos[where f="fact" and lb="lb_exp_horner prec" and ub="ub_exp_horner prec" and j'=0 and s=1,
OF assms f_eq lb_exp_horner.simps ub_exp_horner.simps]
@@ -1462,7 +1462,8 @@
finally have "0 < Ifloat ((?horner x) ^ num)" .
}
ultimately show ?thesis
- unfolding lb_exp.simps if_not_P[OF `\<not> 0 < x`] Let_def by (cases "floor_fl x", cases "x < - 1", auto simp add: le_float_def less_float_def normfloat)
+ unfolding lb_exp.simps if_not_P[OF `\<not> 0 < x`] Let_def
+ by (cases "floor_fl x", cases "x < - 1", auto simp add: float_power le_float_def less_float_def)
qed
lemma exp_boundaries': assumes "x \<le> 0"
@@ -1631,10 +1632,10 @@
lemma ln_bounds:
assumes "0 \<le> x" and "x < 1"
- shows "(\<Sum>i=0..<2*n. -1^i * (1 / real (i + 1)) * x^(Suc i)) \<le> ln (x + 1)" (is "?lb")
- and "ln (x + 1) \<le> (\<Sum>i=0..<2*n + 1. -1^i * (1 / real (i + 1)) * x^(Suc i))" (is "?ub")
+ shows "(\<Sum>i=0..<2*n. -1^i * (1 / real (i + 1)) * x ^ (Suc i)) \<le> ln (x + 1)" (is "?lb")
+ and "ln (x + 1) \<le> (\<Sum>i=0..<2*n + 1. -1^i * (1 / real (i + 1)) * x ^ (Suc i))" (is "?ub")
proof -
- let "?a n" = "(1/real (n +1)) * x^(Suc n)"
+ let "?a n" = "(1/real (n +1)) * x ^ (Suc n)"
have ln_eq: "(\<Sum> i. -1^i * ?a i) = ln (x + 1)"
using ln_series[of "x + 1"] `0 \<le> x` `x < 1` by auto
@@ -2479,7 +2480,7 @@
fun lift_var (Free (varname, _)) = (case AList.lookup (op =) bound_eqs varname of
SOME bound => bound
| NONE => raise TERM ("No bound equations found for " ^ varname, []))
- | lift_var t = raise TERM ("Can not convert expression " ^
+ | lift_var t = raise TERM ("Can not convert expression " ^
(Syntax.string_of_term ctxt t), [t])
val _ $ vs = HOLogic.dest_Trueprop (Logic.strip_imp_concl goal')
--- a/src/HOL/Decision_Procs/Dense_Linear_Order.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Decision_Procs/Dense_Linear_Order.thy Mon May 11 17:20:52 2009 +0200
@@ -639,7 +639,7 @@
interpretation class_ordered_field_dense_linear_order: constr_dense_linear_order
"op <=" "op <"
- "\<lambda> x y. 1/2 * ((x::'a::{ordered_field,recpower,number_ring}) + y)"
+ "\<lambda> x y. 1/2 * ((x::'a::{ordered_field,number_ring}) + y)"
proof (unfold_locales, dlo, dlo, auto)
fix x y::'a assume lt: "x < y"
from less_half_sum[OF lt] show "x < (x + y) /2" by simp
--- a/src/HOL/Decision_Procs/cooper_tac.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Decision_Procs/cooper_tac.ML Mon May 11 17:20:52 2009 +0200
@@ -76,14 +76,14 @@
@{thm "div_by_1"}, @{thm "mod_by_1"}, @{thm "div_1"}, @{thm "mod_1"},
Suc_plus1]
addsimps @{thms add_ac}
- addsimprocs [cancel_div_mod_proc]
+ addsimprocs [cancel_div_mod_nat_proc, cancel_div_mod_int_proc]
val simpset0 = HOL_basic_ss
addsimps [mod_div_equality', Suc_plus1]
addsimps comp_arith
addsplits [split_zdiv, split_zmod, split_div', @{thm "split_min"}, @{thm "split_max"}]
(* Simp rules for changing (n::int) to int n *)
val simpset1 = HOL_basic_ss
- addsimps [nat_number_of_def, zdvd_int] @ map (fn r => r RS sym)
+ addsimps [@{thm nat_number_of_def}, zdvd_int] @ map (fn r => r RS sym)
[@{thm int_int_eq}, @{thm zle_int}, @{thm zless_int}, @{thm zadd_int}, @{thm zmult_int}]
addsplits [zdiff_int_split]
(*simp rules for elimination of int n*)
--- a/src/HOL/Decision_Procs/ex/Dense_Linear_Order_Ex.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Decision_Procs/ex/Dense_Linear_Order_Ex.thy Mon May 11 17:20:52 2009 +0200
@@ -7,147 +7,147 @@
begin
lemma
- "\<exists>(y::'a::{ordered_field,recpower,number_ring, division_by_zero}) <2. x + 3* y < 0 \<and> x - y >0"
+ "\<exists>(y::'a::{ordered_field,number_ring, division_by_zero}) <2. x + 3* y < 0 \<and> x - y >0"
by ferrack
-lemma "~ (ALL x (y::'a::{ordered_field,recpower,number_ring, division_by_zero}). x < y --> 10*x < 11*y)"
+lemma "~ (ALL x (y::'a::{ordered_field,number_ring, division_by_zero}). x < y --> 10*x < 11*y)"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. x < y --> (10*(x + 5*y + -1) < 60*y)"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y. x < y --> (10*(x + 5*y + -1) < 60*y)"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. x ~= y --> x < y"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y. x ~= y --> x < y"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. (x ~= y & 10*x ~= 9*y & 10*x < y) --> x < y"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y. (x ~= y & 10*x ~= 9*y & 10*x < y) --> x < y"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. (x ~= y & 5*x <= y) --> 500*x <= 100*y"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y. (x ~= y & 5*x <= y) --> 500*x <= 100*y"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (EX (y::'a::{ordered_field,recpower,number_ring, division_by_zero}). 4*x + 3*y <= 0 & 4*x + 3*y >= -1)"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}). (EX (y::'a::{ordered_field,number_ring, division_by_zero}). 4*x + 3*y <= 0 & 4*x + 3*y >= -1)"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) < 0. (EX (y::'a::{ordered_field,recpower,number_ring, division_by_zero}) > 0. 7*x + y > 0 & x - y <= 9)"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) < 0. (EX (y::'a::{ordered_field,number_ring, division_by_zero}) > 0. 7*x + y > 0 & x - y <= 9)"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (0 < x & x < 1) --> (ALL y > 1. x + y ~= 1)"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}). (0 < x & x < 1) --> (ALL y > 1. x + y ~= 1)"
by ferrack
-lemma "EX x. (ALL (y::'a::{ordered_field,recpower,number_ring, division_by_zero}). y < 2 --> 2*(y - x) \<le> 0 )"
+lemma "EX x. (ALL (y::'a::{ordered_field,number_ring, division_by_zero}). y < 2 --> 2*(y - x) \<le> 0 )"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). x < 10 | x > 20 | (EX y. y>= 0 & y <= 10 & x+y = 20)"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}). x < 10 | x > 20 | (EX y. y>= 0 & y <= 10 & x+y = 20)"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z. x + y < z --> y >= z --> x < 0"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y z. x + y < z --> y >= z --> x < 0"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z. x + 7*y < 5* z & 5*y >= 7*z & x < 0"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y z. x + 7*y < 5* z & 5*y >= 7*z & x < 0"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z. abs (x + y) <= z --> (abs z = z)"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y z. abs (x + y) <= z --> (abs z = z)"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z. x + 7*y - 5* z < 0 & 5*y + 7*z + 3*x < 0"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y z. x + 7*y - 5* z < 0 & 5*y + 7*z + 3*x < 0"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z. (abs (5*x+3*y+z) <= 5*x+3*y+z & abs (5*x+3*y+z) >= - (5*x+3*y+z)) | (abs (5*x+3*y+z) >= 5*x+3*y+z & abs (5*x+3*y+z) <= - (5*x+3*y+z))"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y z. (abs (5*x+3*y+z) <= 5*x+3*y+z & abs (5*x+3*y+z) >= - (5*x+3*y+z)) | (abs (5*x+3*y+z) >= 5*x+3*y+z & abs (5*x+3*y+z) <= - (5*x+3*y+z))"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. x < y --> (EX z>0. x+z = y)"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y. x < y --> (EX z>0. x+z = y)"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. x < y --> (EX z>0. x+z = y)"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y. x < y --> (EX z>0. x+z = y)"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. (EX z>0. abs (x - y) <= z )"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y. (EX z>0. abs (x - y) <= z )"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. (ALL z<0. (z < x --> z <= y) & (z > y --> z >= x))"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y. (ALL z<0. (z < x --> z <= y) & (z > y --> z >= x))"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. (ALL z>=0. abs (3*x+7*y) <= 2*z + 1)"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y. (ALL z>=0. abs (3*x+7*y) <= 2*z + 1)"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. (ALL z<0. (z < x --> z <= y) & (z > y --> z >= x))"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y. (ALL z<0. (z < x --> z <= y) & (z > y --> z >= x))"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero})>0. (ALL y. (EX z. 13* abs z \<noteq> abs (12*y - x) & 5*x - 3*(abs y) <= 7*z))"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero})>0. (ALL y. (EX z. 13* abs z \<noteq> abs (12*y - x) & 5*x - 3*(abs y) <= 7*z))"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). abs (4*x + 17) < 4 & (ALL y . abs (x*34 - 34*y - 9) \<noteq> 0 \<longrightarrow> (EX z. 5*x - 3*abs y <= 7*z))"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}). abs (4*x + 17) < 4 & (ALL y . abs (x*34 - 34*y - 9) \<noteq> 0 \<longrightarrow> (EX z. 5*x - 3*abs y <= 7*z))"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (EX y > abs (23*x - 9). (ALL z > abs (3*y - 19* abs x). x+z > 2*y))"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}). (EX y > abs (23*x - 9). (ALL z > abs (3*y - 19* abs x). x+z > 2*y))"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (EX y< abs (3*x - 1). (ALL z >= (3*abs x - 1). abs (12*x - 13*y + 19*z) > abs (23*x) ))"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}). (EX y< abs (3*x - 1). (ALL z >= (3*abs x - 1). abs (12*x - 13*y + 19*z) > abs (23*x) ))"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). abs x < 100 & (ALL y > x. (EX z<2*y - x. 5*x - 3*y <= 7*z))"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}). abs x < 100 & (ALL y > x. (EX z<2*y - x. 5*x - 3*y <= 7*z))"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z w. 7*x<3*y --> 5*y < 7*z --> z < 2*w --> 7*(2*w-x) > 2*y"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y z w. 7*x<3*y --> 5*y < 7*z --> z < 2*w --> 7*(2*w-x) > 2*y"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z w. 5*x + 3*z - 17*w + abs (y - 8*x + z) <= 89"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y z w. 5*x + 3*z - 17*w + abs (y - 8*x + z) <= 89"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z w. 5*x + 3*z - 17*w + 7* (y - 8*x + z) <= max y (7*z - x + w)"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y z w. 5*x + 3*z - 17*w + 7* (y - 8*x + z) <= max y (7*z - x + w)"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z w. min (5*x + 3*z) (17*w) + 5* abs (y - 8*x + z) <= max y (7*z - x + w)"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y z w. min (5*x + 3*z) (17*w) + 5* abs (y - 8*x + z) <= max y (7*z - x + w)"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z. (EX w >= (x+y+z). w <= abs x + abs y + abs z)"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y z. (EX w >= (x+y+z). w <= abs x + abs y + abs z)"
by ferrack
-lemma "~(ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (EX y z w. 3* x + z*4 = 3*y & x + y < z & x> w & 3*x < w + y))"
+lemma "~(ALL (x::'a::{ordered_field,number_ring, division_by_zero}). (EX y z w. 3* x + z*4 = 3*y & x + y < z & x> w & 3*x < w + y))"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. (EX z w. abs (x-y) = (z-w) & z*1234 < 233*x & w ~= y)"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y. (EX z w. abs (x-y) = (z-w) & z*1234 < 233*x & w ~= y)"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (EX y z w. min (5*x + 3*z) (17*w) + 5* abs (y - 8*x + z) <= max y (7*z - x + w))"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}). (EX y z w. min (5*x + 3*z) (17*w) + 5* abs (y - 8*x + z) <= max y (7*z - x + w))"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z. (ALL w >= abs (x+y+z). w >= abs x + abs y + abs z)"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y z. (ALL w >= abs (x+y+z). w >= abs x + abs y + abs z)"
by ferrack
-lemma "EX z. (ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. (EX w >= (x+y+z). w <= abs x + abs y + abs z))"
+lemma "EX z. (ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y. (EX w >= (x+y+z). w <= abs x + abs y + abs z))"
by ferrack
-lemma "EX z. (ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) < abs z. (EX y w. x< y & x < z & x> w & 3*x < w + y))"
+lemma "EX z. (ALL (x::'a::{ordered_field,number_ring, division_by_zero}) < abs z. (EX y w. x< y & x < z & x> w & 3*x < w + y))"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y. (EX z. (ALL w. abs (x-y) = abs (z-w) --> z < x & w ~= y))"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}) y. (EX z. (ALL w. abs (x-y) = abs (z-w) --> z < x & w ~= y))"
by ferrack
-lemma "EX y. (ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (EX z w. min (5*x + 3*z) (17*w) + 5* abs (y - 8*x + z) <= max y (7*z - x + w)))"
+lemma "EX y. (ALL (x::'a::{ordered_field,number_ring, division_by_zero}). (EX z w. min (5*x + 3*z) (17*w) + 5* abs (y - 8*x + z) <= max y (7*z - x + w)))"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) z. (ALL w >= 13*x - 4*z. (EX y. w >= abs x + abs y + z))"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) z. (ALL w >= 13*x - 4*z. (EX y. w >= abs x + abs y + z))"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (ALL y < x. (EX z > (x+y).
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}). (ALL y < x. (EX z > (x+y).
(ALL w. 5*w + 10*x - z >= y --> w + 7*x + 3*z >= 2*y)))"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (ALL y. (EX z > y.
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}). (ALL y. (EX z > y.
(ALL w . w < 13 --> w + 10*x - z >= y --> 5*w + 7*x + 13*z >= 2*y)))"
by ferrack
-lemma "EX (x::'a::{ordered_field,recpower,number_ring, division_by_zero}) y z w. min (5*x + 3*z) (17*w) + 5* abs (y - 8*x + z) <= max y (7*z - x + w)"
+lemma "EX (x::'a::{ordered_field,number_ring, division_by_zero}) y z w. min (5*x + 3*z) (17*w) + 5* abs (y - 8*x + z) <= max y (7*z - x + w)"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (EX y. (ALL z>19. y <= x + z & (EX w. abs (y - x) < w)))"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}). (EX y. (ALL z>19. y <= x + z & (EX w. abs (y - x) < w)))"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (EX y. (ALL z>19. y <= x + z & (EX w. abs (x + z) < w - y)))"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}). (EX y. (ALL z>19. y <= x + z & (EX w. abs (x + z) < w - y)))"
by ferrack
-lemma "ALL (x::'a::{ordered_field,recpower,number_ring, division_by_zero}). (EX y. abs y ~= abs x & (ALL z> max x y. (EX w. w ~= y & w ~= z & 3*w - z >= x + y)))"
+lemma "ALL (x::'a::{ordered_field,number_ring, division_by_zero}). (EX y. abs y ~= abs x & (ALL z> max x y. (EX w. w ~= y & w ~= z & 3*w - z >= x + y)))"
by ferrack
end
--- a/src/HOL/Decision_Procs/mir_tac.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Decision_Procs/mir_tac.ML Mon May 11 17:20:52 2009 +0200
@@ -99,7 +99,7 @@
@{thm "div_by_1"}, @{thm "mod_by_1"}, @{thm "div_1"}, @{thm "mod_1"},
@{thm "Suc_plus1"}]
addsimps @{thms add_ac}
- addsimprocs [cancel_div_mod_proc]
+ addsimprocs [cancel_div_mod_nat_proc, cancel_div_mod_int_proc]
val simpset0 = HOL_basic_ss
addsimps [mod_div_equality', Suc_plus1]
addsimps comp_ths
--- a/src/HOL/Deriv.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Deriv.thy Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title : Deriv.thy
- ID : $Id$
Author : Jacques D. Fleuriot
Copyright : 1998 University of Cambridge
Conversion to Isar and new proofs by Lawrence C Paulson, 2004
@@ -197,7 +196,7 @@
done
lemma DERIV_power_Suc:
- fixes f :: "'a \<Rightarrow> 'a::{real_normed_field,recpower}"
+ fixes f :: "'a \<Rightarrow> 'a::{real_normed_field}"
assumes f: "DERIV f x :> D"
shows "DERIV (\<lambda>x. f x ^ Suc n) x :> (1 + of_nat n) * (D * f x ^ n)"
proof (induct n)
@@ -211,7 +210,7 @@
qed
lemma DERIV_power:
- fixes f :: "'a \<Rightarrow> 'a::{real_normed_field,recpower}"
+ fixes f :: "'a \<Rightarrow> 'a::{real_normed_field}"
assumes f: "DERIV f x :> D"
shows "DERIV (\<lambda>x. f x ^ n) x :> of_nat n * (D * f x ^ (n - Suc 0))"
by (cases "n", simp, simp add: DERIV_power_Suc f del: power_Suc)
@@ -287,20 +286,20 @@
text{*Power of -1*}
lemma DERIV_inverse:
- fixes x :: "'a::{real_normed_field,recpower}"
+ fixes x :: "'a::{real_normed_field}"
shows "x \<noteq> 0 ==> DERIV (%x. inverse(x)) x :> (-(inverse x ^ Suc (Suc 0)))"
by (drule DERIV_inverse' [OF DERIV_ident]) simp
text{*Derivative of inverse*}
lemma DERIV_inverse_fun:
- fixes x :: "'a::{real_normed_field,recpower}"
+ fixes x :: "'a::{real_normed_field}"
shows "[| DERIV f x :> d; f(x) \<noteq> 0 |]
==> DERIV (%x. inverse(f x)) x :> (- (d * inverse(f(x) ^ Suc (Suc 0))))"
by (drule (1) DERIV_inverse') (simp add: mult_ac nonzero_inverse_mult_distrib)
text{*Derivative of quotient*}
lemma DERIV_quotient:
- fixes x :: "'a::{real_normed_field,recpower}"
+ fixes x :: "'a::{real_normed_field}"
shows "[| DERIV f x :> d; DERIV g x :> e; g(x) \<noteq> 0 |]
==> DERIV (%y. f(y) / (g y)) x :> (d*g(x) - (e*f(x))) / (g(x) ^ Suc (Suc 0))"
by (drule (2) DERIV_divide) (simp add: mult_commute)
@@ -404,7 +403,7 @@
unfolding divide_inverse using prems by simp
lemma differentiable_power [simp]:
- fixes f :: "'a::{recpower,real_normed_field} \<Rightarrow> 'a"
+ fixes f :: "'a::{real_normed_field} \<Rightarrow> 'a"
assumes "f differentiable x"
shows "(\<lambda>x. f x ^ n) differentiable x"
by (induct n, simp, simp add: prems)
--- a/src/HOL/Divides.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Divides.thy Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title: HOL/Divides.thy
- ID: $Id$
Author: Lawrence C Paulson, Cambridge University Computer Laboratory
Copyright 1999 University of Cambridge
*)
@@ -20,11 +19,12 @@
subsection {* Abstract division in commutative semirings. *}
-class semiring_div = comm_semiring_1_cancel + div +
+class semiring_div = comm_semiring_1_cancel + no_zero_divisors + div +
assumes mod_div_equality: "a div b * b + a mod b = a"
and div_by_0 [simp]: "a div 0 = 0"
and div_0 [simp]: "0 div a = 0"
and div_mult_self1 [simp]: "b \<noteq> 0 \<Longrightarrow> (a + c * b) div b = c + a div b"
+ and div_mult_mult1 [simp]: "c \<noteq> 0 \<Longrightarrow> (c * a) div (c * b) = a div b"
begin
text {* @{const div} and @{const mod} *}
@@ -38,16 +38,16 @@
by (simp only: add_ac)
lemma div_mod_equality: "((a div b) * b + a mod b) + c = a + c"
-by (simp add: mod_div_equality)
+ by (simp add: mod_div_equality)
lemma div_mod_equality2: "(b * (a div b) + a mod b) + c = a + c"
-by (simp add: mod_div_equality2)
+ by (simp add: mod_div_equality2)
lemma mod_by_0 [simp]: "a mod 0 = a"
-using mod_div_equality [of a zero] by simp
+ using mod_div_equality [of a zero] by simp
lemma mod_0 [simp]: "0 mod a = 0"
-using mod_div_equality [of zero a] div_0 by simp
+ using mod_div_equality [of zero a] div_0 by simp
lemma div_mult_self2 [simp]:
assumes "b \<noteq> 0"
@@ -72,7 +72,7 @@
qed
lemma mod_mult_self2 [simp]: "(a + b * c) mod b = a mod b"
-by (simp add: mult_commute [of b])
+ by (simp add: mult_commute [of b])
lemma div_mult_self1_is_id [simp]: "b \<noteq> 0 \<Longrightarrow> b * a div b = a"
using div_mult_self2 [of b 0 a] by simp
@@ -238,9 +238,9 @@
by (simp only: mod_add_eq [symmetric])
qed
-lemma div_add[simp]: "z dvd x \<Longrightarrow> z dvd y
+lemma div_add [simp]: "z dvd x \<Longrightarrow> z dvd y
\<Longrightarrow> (x + y) div z = x div z + y div z"
-by(cases "z=0", simp, unfold dvd_def, auto simp add: algebra_simps)
+by (cases "z = 0", simp, unfold dvd_def, auto simp add: algebra_simps)
text {* Multiplication respects modular equivalence. *}
@@ -297,24 +297,45 @@
finally show ?thesis .
qed
+lemma div_mult_div_if_dvd:
+ "y dvd x \<Longrightarrow> z dvd w \<Longrightarrow> (x div y) * (w div z) = (x * w) div (y * z)"
+ apply (cases "y = 0", simp)
+ apply (cases "z = 0", simp)
+ apply (auto elim!: dvdE simp add: algebra_simps)
+ apply (subst mult_assoc [symmetric])
+ apply (simp add: no_zero_divisors)
+ done
+
+lemma div_mult_mult2 [simp]:
+ "c \<noteq> 0 \<Longrightarrow> (a * c) div (b * c) = a div b"
+ by (drule div_mult_mult1) (simp add: mult_commute)
+
+lemma div_mult_mult1_if [simp]:
+ "(c * a) div (c * b) = (if c = 0 then 0 else a div b)"
+ by simp_all
+
+lemma mod_mult_mult1:
+ "(c * a) mod (c * b) = c * (a mod b)"
+proof (cases "c = 0")
+ case True then show ?thesis by simp
+next
+ case False
+ from mod_div_equality
+ have "((c * a) div (c * b)) * (c * b) + (c * a) mod (c * b) = c * a" .
+ with False have "c * ((a div b) * b + a mod b) + (c * a) mod (c * b)
+ = c * a + c * (a mod b)" by (simp add: algebra_simps)
+ with mod_div_equality show ?thesis by simp
+qed
+
+lemma mod_mult_mult2:
+ "(a * c) mod (b * c) = (a mod b) * c"
+ using mod_mult_mult1 [of c a b] by (simp add: mult_commute)
+
end
-lemma div_mult_div_if_dvd: "(y::'a::{semiring_div,no_zero_divisors}) dvd x \<Longrightarrow>
- z dvd w \<Longrightarrow> (x div y) * (w div z) = (x * w) div (y * z)"
-unfolding dvd_def
- apply clarify
- apply (case_tac "y = 0")
- apply simp
- apply (case_tac "z = 0")
- apply simp
- apply (simp add: algebra_simps)
- apply (subst mult_assoc [symmetric])
- apply (simp add: no_zero_divisors)
-done
-
-
-lemma div_power: "(y::'a::{semiring_div,no_zero_divisors,recpower}) dvd x \<Longrightarrow>
- (x div y)^n = x^n div y^n"
+lemma div_power:
+ "(y::'a::{semiring_div,no_zero_divisors,power}) dvd x \<Longrightarrow>
+ (x div y) ^ n = x ^ n div y ^ n"
apply (induct n)
apply simp
apply(simp add: div_mult_div_if_dvd dvd_power_same)
@@ -398,15 +419,17 @@
@{term "q\<Colon>nat"}(uotient) and @{term "r\<Colon>nat"}(emainder).
*}
-definition divmod_rel :: "nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool" where
- "divmod_rel m n q r \<longleftrightarrow> m = q * n + r \<and> (if n > 0 then 0 \<le> r \<and> r < n else q = 0)"
+definition divmod_rel :: "nat \<Rightarrow> nat \<Rightarrow> nat \<times> nat \<Rightarrow> bool" where
+ "divmod_rel m n qr \<longleftrightarrow>
+ m = fst qr * n + snd qr \<and>
+ (if n = 0 then fst qr = 0 else if n > 0 then 0 \<le> snd qr \<and> snd qr < n else n < snd qr \<and> snd qr \<le> 0)"
text {* @{const divmod_rel} is total: *}
lemma divmod_rel_ex:
- obtains q r where "divmod_rel m n q r"
+ obtains q r where "divmod_rel m n (q, r)"
proof (cases "n = 0")
- case True with that show thesis
+ case True with that show thesis
by (auto simp add: divmod_rel_def)
next
case False
@@ -436,13 +459,14 @@
text {* @{const divmod_rel} is injective: *}
-lemma divmod_rel_unique_div:
- assumes "divmod_rel m n q r"
- and "divmod_rel m n q' r'"
- shows "q = q'"
+lemma divmod_rel_unique:
+ assumes "divmod_rel m n qr"
+ and "divmod_rel m n qr'"
+ shows "qr = qr'"
proof (cases "n = 0")
case True with assms show ?thesis
- by (simp add: divmod_rel_def)
+ by (cases qr, cases qr')
+ (simp add: divmod_rel_def)
next
case False
have aux: "\<And>q r q' r'. q' * n + r' = q * n + r \<Longrightarrow> r < n \<Longrightarrow> q' \<le> (q\<Colon>nat)"
@@ -450,18 +474,11 @@
apply (subst less_iff_Suc_add)
apply (auto simp add: add_mult_distrib)
done
- from `n \<noteq> 0` assms show ?thesis
- by (auto simp add: divmod_rel_def
- intro: order_antisym dest: aux sym)
-qed
-
-lemma divmod_rel_unique_mod:
- assumes "divmod_rel m n q r"
- and "divmod_rel m n q' r'"
- shows "r = r'"
-proof -
- from assms have "q = q'" by (rule divmod_rel_unique_div)
- with assms show ?thesis by (simp add: divmod_rel_def)
+ from `n \<noteq> 0` assms have "fst qr = fst qr'"
+ by (auto simp add: divmod_rel_def intro: order_antisym dest: aux sym)
+ moreover from this assms have "snd qr = snd qr'"
+ by (simp add: divmod_rel_def)
+ ultimately show ?thesis by (cases qr, cases qr') simp
qed
text {*
@@ -473,7 +490,21 @@
begin
definition divmod :: "nat \<Rightarrow> nat \<Rightarrow> nat \<times> nat" where
- [code del]: "divmod m n = (THE (q, r). divmod_rel m n q r)"
+ [code del]: "divmod m n = (THE qr. divmod_rel m n qr)"
+
+lemma divmod_rel_divmod:
+ "divmod_rel m n (divmod m n)"
+proof -
+ from divmod_rel_ex
+ obtain qr where rel: "divmod_rel m n qr" .
+ then show ?thesis
+ by (auto simp add: divmod_def intro: theI elim: divmod_rel_unique)
+qed
+
+lemma divmod_eq:
+ assumes "divmod_rel m n qr"
+ shows "divmod m n = qr"
+ using assms by (auto intro: divmod_rel_unique divmod_rel_divmod)
definition div_nat where
"m div n = fst (divmod m n)"
@@ -485,30 +516,18 @@
"divmod m n = (m div n, m mod n)"
unfolding div_nat_def mod_nat_def by simp
-lemma divmod_eq:
- assumes "divmod_rel m n q r"
- shows "divmod m n = (q, r)"
- using assms by (auto simp add: divmod_def
- dest: divmod_rel_unique_div divmod_rel_unique_mod)
-
lemma div_eq:
- assumes "divmod_rel m n q r"
+ assumes "divmod_rel m n (q, r)"
shows "m div n = q"
- using assms by (auto dest: divmod_eq simp add: div_nat_def)
+ using assms by (auto dest: divmod_eq simp add: divmod_div_mod)
lemma mod_eq:
- assumes "divmod_rel m n q r"
+ assumes "divmod_rel m n (q, r)"
shows "m mod n = r"
- using assms by (auto dest: divmod_eq simp add: mod_nat_def)
+ using assms by (auto dest: divmod_eq simp add: divmod_div_mod)
-lemma divmod_rel: "divmod_rel m n (m div n) (m mod n)"
-proof -
- from divmod_rel_ex
- obtain q r where rel: "divmod_rel m n q r" .
- moreover with div_eq mod_eq have "m div n = q" and "m mod n = r"
- by simp_all
- ultimately show ?thesis by simp
-qed
+lemma divmod_rel: "divmod_rel m n (m div n, m mod n)"
+ by (simp add: div_nat_def mod_nat_def divmod_rel_divmod)
lemma divmod_zero:
"divmod m 0 = (0, m)"
@@ -531,10 +550,10 @@
assumes "0 < n" and "n \<le> m"
shows "divmod m n = (Suc ((m - n) div n), (m - n) mod n)"
proof -
- from divmod_rel have divmod_m_n: "divmod_rel m n (m div n) (m mod n)" .
+ from divmod_rel have divmod_m_n: "divmod_rel m n (m div n, m mod n)" .
with assms have m_div_n: "m div n \<ge> 1"
by (cases "m div n") (auto simp add: divmod_rel_def)
- from assms divmod_m_n have "divmod_rel (m - n) n (m div n - Suc 0) (m mod n)"
+ from assms divmod_m_n have "divmod_rel (m - n) n (m div n - Suc 0, m mod n)"
by (cases "m div n") (auto simp add: divmod_rel_def)
with divmod_eq have "divmod (m - n) n = (m div n - Suc 0, m mod n)" by simp
moreover from divmod_div_mod have "divmod (m - n) n = ((m - n) div n, (m - n) mod n)" .
@@ -569,55 +588,74 @@
shows "m mod n = (m - n) mod n"
using assms divmod_step divmod_div_mod by (cases "n = 0") simp_all
-instance proof
- fix m n :: nat show "m div n * n + m mod n = m"
- using divmod_rel [of m n] by (simp add: divmod_rel_def)
-next
- fix n :: nat show "n div 0 = 0"
- using divmod_zero divmod_div_mod [of n 0] by simp
-next
- fix n :: nat show "0 div n = 0"
- using divmod_rel [of 0 n] by (cases n) (simp_all add: divmod_rel_def)
-next
- fix m n q :: nat assume "n \<noteq> 0" then show "(q + m * n) div n = m + q div n"
- by (induct m) (simp_all add: le_div_geq)
+instance proof -
+ have [simp]: "\<And>n::nat. n div 0 = 0"
+ by (simp add: div_nat_def divmod_zero)
+ have [simp]: "\<And>n::nat. 0 div n = 0"
+ proof -
+ fix n :: nat
+ show "0 div n = 0"
+ by (cases "n = 0") simp_all
+ qed
+ show "OFCLASS(nat, semiring_div_class)" proof
+ fix m n :: nat
+ show "m div n * n + m mod n = m"
+ using divmod_rel [of m n] by (simp add: divmod_rel_def)
+ next
+ fix m n q :: nat
+ assume "n \<noteq> 0"
+ then show "(q + m * n) div n = m + q div n"
+ by (induct m) (simp_all add: le_div_geq)
+ next
+ fix m n q :: nat
+ assume "m \<noteq> 0"
+ then show "(m * n) div (m * q) = n div q"
+ proof (cases "n \<noteq> 0 \<and> q \<noteq> 0")
+ case False then show ?thesis by auto
+ next
+ case True with `m \<noteq> 0`
+ have "m > 0" and "n > 0" and "q > 0" by auto
+ then have "\<And>a b. divmod_rel n q (a, b) \<Longrightarrow> divmod_rel (m * n) (m * q) (a, m * b)"
+ by (auto simp add: divmod_rel_def) (simp_all add: algebra_simps)
+ moreover from divmod_rel have "divmod_rel n q (n div q, n mod q)" .
+ ultimately have "divmod_rel (m * n) (m * q) (n div q, m * (n mod q))" .
+ then show ?thesis by (simp add: div_eq)
+ qed
+ qed simp_all
qed
end
text {* Simproc for cancelling @{const div} and @{const mod} *}
-(*lemmas mod_div_equality_nat = semiring_div_class.times_div_mod_plus_zero_one.mod_div_equality [of "m\<Colon>nat" n, standard]
-lemmas mod_div_equality2_nat = mod_div_equality2 [of "n\<Colon>nat" m, standard*)
+ML {*
+local
+
+structure CancelDivMod = CancelDivModFun(struct
-ML {*
-structure CancelDivModData =
-struct
-
-val div_name = @{const_name div};
-val mod_name = @{const_name mod};
-val mk_binop = HOLogic.mk_binop;
-val mk_sum = Nat_Arith.mk_sum;
-val dest_sum = Nat_Arith.dest_sum;
+ val div_name = @{const_name div};
+ val mod_name = @{const_name mod};
+ val mk_binop = HOLogic.mk_binop;
+ val mk_sum = Nat_Arith.mk_sum;
+ val dest_sum = Nat_Arith.dest_sum;
-(*logic*)
+ val div_mod_eqs = map mk_meta_eq [@{thm div_mod_equality}, @{thm div_mod_equality2}];
-val div_mod_eqs = map mk_meta_eq [@{thm div_mod_equality}, @{thm div_mod_equality2}]
-
-val trans = trans
+ val trans = trans;
-val prove_eq_sums =
- let val simps = @{thm add_0} :: @{thm add_0_right} :: @{thms add_ac}
- in Arith_Data.prove_conv2 all_tac (Arith_Data.simp_all_tac simps) end;
+ val prove_eq_sums = Arith_Data.prove_conv2 all_tac (Arith_Data.simp_all_tac
+ (@{thm monoid_add_class.add_0_left} :: @{thm monoid_add_class.add_0_right} :: @{thms add_ac}))
-end;
+end)
-structure CancelDivMod = CancelDivModFun(CancelDivModData);
+in
-val cancel_div_mod_proc = Simplifier.simproc (the_context ())
+val cancel_div_mod_nat_proc = Simplifier.simproc (the_context ())
"cancel_div_mod" ["(m::nat) + n"] (K CancelDivMod.proc);
-Addsimprocs[cancel_div_mod_proc];
+val _ = Addsimprocs [cancel_div_mod_nat_proc];
+
+end
*}
text {* code generator setup *}
@@ -658,7 +696,7 @@
fixes m n :: nat
assumes "n > 0"
shows "m mod n < (n::nat)"
- using assms divmod_rel unfolding divmod_rel_def by auto
+ using assms divmod_rel [of m n] unfolding divmod_rel_def by auto
lemma mod_less_eq_dividend [simp]:
fixes m n :: nat
@@ -700,18 +738,19 @@
subsubsection {* Quotient and Remainder *}
lemma divmod_rel_mult1_eq:
- "[| divmod_rel b c q r; c > 0 |]
- ==> divmod_rel (a*b) c (a*q + a*r div c) (a*r mod c)"
+ "divmod_rel b c (q, r) \<Longrightarrow> c > 0
+ \<Longrightarrow> divmod_rel (a * b) c (a * q + a * r div c, a * r mod c)"
by (auto simp add: split_ifs divmod_rel_def algebra_simps)
-lemma div_mult1_eq: "(a*b) div c = a*(b div c) + a*(b mod c) div (c::nat)"
+lemma div_mult1_eq:
+ "(a * b) div c = a * (b div c) + a * (b mod c) div (c::nat)"
apply (cases "c = 0", simp)
apply (blast intro: divmod_rel [THEN divmod_rel_mult1_eq, THEN div_eq])
done
lemma divmod_rel_add1_eq:
- "[| divmod_rel a c aq ar; divmod_rel b c bq br; c > 0 |]
- ==> divmod_rel (a + b) c (aq + bq + (ar+br) div c) ((ar + br) mod c)"
+ "divmod_rel a c (aq, ar) \<Longrightarrow> divmod_rel b c (bq, br) \<Longrightarrow> c > 0
+ \<Longrightarrow> divmod_rel (a + b) c (aq + bq + (ar + br) div c, (ar + br) mod c)"
by (auto simp add: split_ifs divmod_rel_def algebra_simps)
(*NOT suitable for rewriting: the RHS has an instance of the LHS*)
@@ -728,8 +767,9 @@
apply (simp add: add_mult_distrib2)
done
-lemma divmod_rel_mult2_eq: "[| divmod_rel a b q r; 0 < b; 0 < c |]
- ==> divmod_rel a (b*c) (q div c) (b*(q mod c) + r)"
+lemma divmod_rel_mult2_eq:
+ "divmod_rel a b (q, r) \<Longrightarrow> 0 < b \<Longrightarrow> 0 < c
+ \<Longrightarrow> divmod_rel a (b * c) (q div c, b *(q mod c) + r)"
by (auto simp add: mult_ac divmod_rel_def add_mult_distrib2 [symmetric] mod_lemma)
lemma div_mult2_eq: "a div (b*c) = (a div b) div (c::nat)"
@@ -745,23 +785,6 @@
done
-subsubsection{*Cancellation of Common Factors in Division*}
-
-lemma div_mult_mult_lemma:
- "[| (0::nat) < b; 0 < c |] ==> (c*a) div (c*b) = a div b"
-by (auto simp add: div_mult2_eq)
-
-lemma div_mult_mult1 [simp]: "(0::nat) < c ==> (c*a) div (c*b) = a div b"
- apply (cases "b = 0")
- apply (auto simp add: linorder_neq_iff [of b] div_mult_mult_lemma)
- done
-
-lemma div_mult_mult2 [simp]: "(0::nat) < c ==> (a*c) div (b*c) = a div b"
- apply (drule div_mult_mult1)
- apply (auto simp add: mult_commute)
- done
-
-
subsubsection{*Further Facts about Quotient and Remainder*}
lemma div_1 [simp]: "m div Suc 0 = m"
@@ -769,7 +792,7 @@
(* Monotonicity of div in first argument *)
-lemma div_le_mono [rule_format]:
+lemma div_le_mono [rule_format (no_asm)]:
"\<forall>m::nat. m \<le> n --> (m div k) \<le> (n div k)"
apply (case_tac "k=0", simp)
apply (induct "n" rule: nat_less_induct, clarify)
@@ -824,12 +847,6 @@
apply (simp_all)
done
-lemma nat_div_eq_0 [simp]: "(n::nat) > 0 ==> ((m div n) = 0) = (m < n)"
-by(auto, subst mod_div_equality [of m n, symmetric], auto)
-
-lemma nat_div_gt_0 [simp]: "(n::nat) > 0 ==> ((m div n) > 0) = (m >= n)"
-by (subst neq0_conv [symmetric], auto)
-
declare div_less_dividend [simp]
text{*A fact for the mutilated chess board*}
@@ -915,21 +932,13 @@
done
lemma dvd_imp_le: "[| k dvd n; 0 < n |] ==> k \<le> (n::nat)"
-by (auto elim!: dvdE) (auto simp add: gr0_conv_Suc)
-
-lemma nat_dvd_not_less: "(0::nat) < m \<Longrightarrow> m < n \<Longrightarrow> \<not> n dvd m"
-by (auto elim!: dvdE) (auto simp add: gr0_conv_Suc)
+ by (auto elim!: dvdE) (auto simp add: gr0_conv_Suc)
lemma dvd_mult_div_cancel: "n dvd m ==> n * (m div n) = (m::nat)"
- apply (subgoal_tac "m mod n = 0")
- apply (simp add: mult_div_cancel)
- apply (simp only: dvd_eq_mod_eq_0)
- done
+ by (simp add: dvd_eq_mod_eq_0 mult_div_cancel)
-lemma nat_zero_less_power_iff [simp]: "(x^n > 0) = (x > (0::nat) | n=0)"
- by (induct n) auto
-
-lemma power_dvd_imp_le: "[|i^m dvd i^n; (1::nat) < i|] ==> m \<le> n"
+lemma power_dvd_imp_le:
+ "i ^ m dvd i ^ n \<Longrightarrow> (1::nat) < i \<Longrightarrow> m \<le> n"
apply (rule power_le_imp_le_exp, assumption)
apply (erule dvd_imp_le, simp)
done
@@ -1001,9 +1010,11 @@
from A B show ?lhs ..
next
assume P: ?lhs
- then have "divmod_rel m n q (m - n * q)"
+ then have "divmod_rel m n (q, m - n * q)"
unfolding divmod_rel_def by (auto simp add: mult_ac)
- then show ?rhs using divmod_rel by (rule divmod_rel_unique_div)
+ with divmod_rel_unique divmod_rel [of m n]
+ have "(q, m - n * q) = (m div n, m mod n)" by auto
+ then show ?rhs by simp
qed
theorem split_div':
@@ -1155,4 +1166,9 @@
with j show ?thesis by blast
qed
+lemma nat_dvd_not_less:
+ fixes m n :: nat
+ shows "0 < m \<Longrightarrow> m < n \<Longrightarrow> \<not> n dvd m"
+by (auto elim!: dvdE) (auto simp add: gr0_conv_Suc)
+
end
--- a/src/HOL/Finite_Set.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Finite_Set.thy Mon May 11 17:20:52 2009 +0200
@@ -365,6 +365,29 @@
lemma finite_Plus: "[| finite A; finite B |] ==> finite (A <+> B)"
by (simp add: Plus_def)
+lemma finite_PlusD:
+ fixes A :: "'a set" and B :: "'b set"
+ assumes fin: "finite (A <+> B)"
+ shows "finite A" "finite B"
+proof -
+ have "Inl ` A \<subseteq> A <+> B" by auto
+ hence "finite (Inl ` A :: ('a + 'b) set)" using fin by(rule finite_subset)
+ thus "finite A" by(rule finite_imageD)(auto intro: inj_onI)
+next
+ have "Inr ` B \<subseteq> A <+> B" by auto
+ hence "finite (Inr ` B :: ('a + 'b) set)" using fin by(rule finite_subset)
+ thus "finite B" by(rule finite_imageD)(auto intro: inj_onI)
+qed
+
+lemma finite_Plus_iff[simp]: "finite (A <+> B) \<longleftrightarrow> finite A \<and> finite B"
+by(auto intro: finite_PlusD finite_Plus)
+
+lemma finite_Plus_UNIV_iff[simp]:
+ "finite (UNIV :: ('a + 'b) set) =
+ (finite (UNIV :: 'a set) & finite (UNIV :: 'b set))"
+by(subst UNIV_Plus_UNIV[symmetric])(rule finite_Plus_iff)
+
+
text {* Sigma of finite sets *}
lemma finite_SigmaI [simp]:
@@ -1563,6 +1586,20 @@
qed
+lemma setsum_Plus:
+ fixes A :: "'a set" and B :: "'b set"
+ assumes fin: "finite A" "finite B"
+ shows "setsum f (A <+> B) = setsum (f \<circ> Inl) A + setsum (f \<circ> Inr) B"
+proof -
+ have "A <+> B = Inl ` A \<union> Inr ` B" by auto
+ moreover from fin have "finite (Inl ` A :: ('a + 'b) set)" "finite (Inr ` B :: ('a + 'b) set)"
+ by(auto intro: finite_imageI)
+ moreover have "Inl ` A \<inter> Inr ` B = ({} :: ('a + 'b) set)" by auto
+ moreover have "inj_on (Inl :: 'a \<Rightarrow> 'a + 'b) A" "inj_on (Inr :: 'b \<Rightarrow> 'a + 'b) B" by(auto intro: inj_onI)
+ ultimately show ?thesis using fin by(simp add: setsum_Un_disjoint setsum_reindex)
+qed
+
+
text {* Commuting outer and inner summation *}
lemma swap_inj_on:
@@ -2047,14 +2084,14 @@
apply (auto simp add: algebra_simps)
done
-lemma setprod_constant: "finite A ==> (\<Prod>x\<in> A. (y::'a::{recpower, comm_monoid_mult})) = y^(card A)"
+lemma setprod_constant: "finite A ==> (\<Prod>x\<in> A. (y::'a::{comm_monoid_mult})) = y^(card A)"
apply (erule finite_induct)
apply (auto simp add: power_Suc)
done
lemma setprod_gen_delta:
assumes fS: "finite S"
- shows "setprod (\<lambda>k. if k=a then b k else c) S = (if a \<in> S then (b a ::'a::{comm_monoid_mult, recpower}) * c^ (card S - 1) else c^ card S)"
+ shows "setprod (\<lambda>k. if k=a then b k else c) S = (if a \<in> S then (b a ::'a::{comm_monoid_mult}) * c^ (card S - 1) else c^ card S)"
proof-
let ?f = "(\<lambda>k. if k=a then b k else c)"
{assume a: "a \<notin> S"
@@ -2091,6 +2128,10 @@
qed
+lemma card_UNIV_unit: "card (UNIV :: unit set) = 1"
+ unfolding UNIV_unit by simp
+
+
subsubsection {* Cardinality of unions *}
lemma card_UN_disjoint:
@@ -2201,6 +2242,10 @@
by (simp add: card_Un_disjoint card_image)
qed
+lemma card_Plus_conv_if:
+ "card (A <+> B) = (if finite A \<and> finite B then card(A) + card(B) else 0)"
+by(auto simp: card_def setsum_Plus simp del: setsum_constant)
+
subsubsection {* Cardinality of the Powerset *}
--- a/src/HOL/Fun.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Fun.thy Mon May 11 17:20:52 2009 +0200
@@ -412,6 +412,9 @@
"f(x:=y) ` A = (if x \<in> A then insert y (f ` (A-{x})) else f ` A)"
by auto
+lemma fun_upd_comp: "f \<circ> (g(x := y)) = (f \<circ> g)(x := f y)"
+by(auto intro: ext)
+
subsection {* @{text override_on} *}
--- a/src/HOL/Groebner_Basis.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Groebner_Basis.thy Mon May 11 17:20:52 2009 +0200
@@ -5,7 +5,7 @@
header {* Semiring normalization and Groebner Bases *}
theory Groebner_Basis
-imports NatBin
+imports Nat_Numeral
uses
"Tools/Groebner_Basis/misc.ML"
"Tools/Groebner_Basis/normalizer_data.ML"
@@ -164,7 +164,7 @@
end
interpretation class_semiring: gb_semiring
- "op +" "op *" "op ^" "0::'a::{comm_semiring_1, recpower}" "1"
+ "op +" "op *" "op ^" "0::'a::{comm_semiring_1}" "1"
proof qed (auto simp add: algebra_simps power_Suc)
lemmas nat_arith =
@@ -242,7 +242,7 @@
interpretation class_ring: gb_ring "op +" "op *" "op ^"
- "0::'a::{comm_semiring_1,recpower,number_ring}" 1 "op -" "uminus"
+ "0::'a::{comm_semiring_1,number_ring}" 1 "op -" "uminus"
proof qed simp_all
@@ -349,9 +349,9 @@
qed
interpretation class_ringb: ringb
- "op +" "op *" "op ^" "0::'a::{idom,recpower,number_ring}" "1" "op -" "uminus"
+ "op +" "op *" "op ^" "0::'a::{idom,number_ring}" "1" "op -" "uminus"
proof(unfold_locales, simp add: algebra_simps power_Suc, auto)
- fix w x y z ::"'a::{idom,recpower,number_ring}"
+ fix w x y z ::"'a::{idom,number_ring}"
assume p: "w * y + x * z = w * z + x * y" and ynz: "y \<noteq> z"
hence ynz': "y - z \<noteq> 0" by simp
from p have "w * y + x* z - w*z - x*y = 0" by simp
@@ -471,7 +471,7 @@
subsection{* Groebner Bases for fields *}
interpretation class_fieldgb:
- fieldgb "op +" "op *" "op ^" "0::'a::{field,recpower,number_ring}" "1" "op -" "uminus" "op /" "inverse" apply (unfold_locales) by (simp_all add: divide_inverse)
+ fieldgb "op +" "op *" "op ^" "0::'a::{field,number_ring}" "1" "op -" "uminus" "op /" "inverse" apply (unfold_locales) by (simp_all add: divide_inverse)
lemma divide_Numeral1: "(x::'a::{field,number_ring}) / Numeral1 = x" by simp
lemma divide_Numeral0: "(x::'a::{field,number_ring, division_by_zero}) / Numeral0 = 0"
@@ -635,7 +635,7 @@
val comp_conv = (Simplifier.rewrite
(HOL_basic_ss addsimps @{thms "Groebner_Basis.comp_arith"}
addsimps ths addsimps simp_thms
- addsimprocs field_cancel_numeral_factors
+ addsimprocs Numeral_Simprocs.field_cancel_numeral_factors
addsimprocs [add_frac_frac_simproc, add_frac_num_simproc,
ord_frac_simproc]
addcongs [@{thm "if_weak_cong"}]))
--- a/src/HOL/HOL.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/HOL.thy Mon May 11 17:20:52 2009 +0200
@@ -5,9 +5,10 @@
header {* The basis of Higher-Order Logic *}
theory HOL
-imports Pure
+imports Pure "~~/src/Tools/Code_Generator"
uses
("Tools/hologic.ML")
+ "~~/src/Tools/auto_solve.ML"
"~~/src/Tools/IsaPlanner/zipper.ML"
"~~/src/Tools/IsaPlanner/isand.ML"
"~~/src/Tools/IsaPlanner/rw_tools.ML"
@@ -27,16 +28,6 @@
"~~/src/Tools/atomize_elim.ML"
"~~/src/Tools/induct.ML"
("~~/src/Tools/induct_tacs.ML")
- "~~/src/Tools/value.ML"
- "~~/src/Tools/code/code_name.ML"
- "~~/src/Tools/code/code_funcgr.ML" (*formal dependency*)
- "~~/src/Tools/code/code_wellsorted.ML"
- "~~/src/Tools/code/code_thingol.ML"
- "~~/src/Tools/code/code_printer.ML"
- "~~/src/Tools/code/code_target.ML"
- "~~/src/Tools/code/code_ml.ML"
- "~~/src/Tools/code/code_haskell.ML"
- "~~/src/Tools/nbe.ML"
("Tools/recfun_codegen.ML")
begin
@@ -1577,6 +1568,56 @@
setup Coherent.setup
+subsubsection {* Reorienting equalities *}
+
+ML {*
+signature REORIENT_PROC =
+sig
+ val init : theory -> theory
+ val add : (term -> bool) -> theory -> theory
+ val proc : morphism -> simpset -> cterm -> thm option
+end;
+
+structure ReorientProc : REORIENT_PROC =
+struct
+ structure Data = TheoryDataFun
+ (
+ type T = term -> bool;
+ val empty = (fn _ => false);
+ val copy = I;
+ val extend = I;
+ fun merge _ (m1, m2) = (fn t => m1 t orelse m2 t);
+ )
+
+ val init = Data.init;
+ fun add m = Data.map (fn matches => fn t => matches t orelse m t);
+ val meta_reorient = @{thm eq_commute [THEN eq_reflection]};
+ fun proc phi ss ct =
+ let
+ val ctxt = Simplifier.the_context ss;
+ val thy = ProofContext.theory_of ctxt;
+ val matches = Data.get thy;
+ in
+ case Thm.term_of ct of
+ (_ $ t $ u) => if matches u then NONE else SOME meta_reorient
+ | _ => NONE
+ end;
+end;
+*}
+
+setup ReorientProc.init
+
+setup {*
+ ReorientProc.add
+ (fn Const(@{const_name HOL.zero}, _) => true
+ | Const(@{const_name HOL.one}, _) => true
+ | _ => false)
+*}
+
+simproc_setup reorient_zero ("0 = x") = ReorientProc.proc
+simproc_setup reorient_one ("1 = x") = ReorientProc.proc
+
+
subsection {* Other simple lemmas and lemma duplicates *}
lemma Let_0 [simp]: "Let 0 f = f 0"
@@ -1674,37 +1715,264 @@
*}
-subsection {* Code generator basics -- see further theory @{text "Code_Setup"} *}
+subsection {* Code generator setup *}
+
+subsubsection {* SML code generator setup *}
+
+use "Tools/recfun_codegen.ML"
+
+setup {*
+ Codegen.setup
+ #> RecfunCodegen.setup
+*}
+
+types_code
+ "bool" ("bool")
+attach (term_of) {*
+fun term_of_bool b = if b then HOLogic.true_const else HOLogic.false_const;
+*}
+attach (test) {*
+fun gen_bool i =
+ let val b = one_of [false, true]
+ in (b, fn () => term_of_bool b) end;
+*}
+ "prop" ("bool")
+attach (term_of) {*
+fun term_of_prop b =
+ HOLogic.mk_Trueprop (if b then HOLogic.true_const else HOLogic.false_const);
+*}
-text {* Equality *}
+consts_code
+ "Trueprop" ("(_)")
+ "True" ("true")
+ "False" ("false")
+ "Not" ("Bool.not")
+ "op |" ("(_ orelse/ _)")
+ "op &" ("(_ andalso/ _)")
+ "If" ("(if _/ then _/ else _)")
+
+setup {*
+let
+
+fun eq_codegen thy defs dep thyname b t gr =
+ (case strip_comb t of
+ (Const ("op =", Type (_, [Type ("fun", _), _])), _) => NONE
+ | (Const ("op =", _), [t, u]) =>
+ let
+ val (pt, gr') = Codegen.invoke_codegen thy defs dep thyname false t gr;
+ val (pu, gr'') = Codegen.invoke_codegen thy defs dep thyname false u gr';
+ val (_, gr''') = Codegen.invoke_tycodegen thy defs dep thyname false HOLogic.boolT gr'';
+ in
+ SOME (Codegen.parens
+ (Pretty.block [pt, Codegen.str " =", Pretty.brk 1, pu]), gr''')
+ end
+ | (t as Const ("op =", _), ts) => SOME (Codegen.invoke_codegen
+ thy defs dep thyname b (Codegen.eta_expand t ts 2) gr)
+ | _ => NONE);
+
+in
+ Codegen.add_codegen "eq_codegen" eq_codegen
+end
+*}
+
+subsubsection {* Equality *}
class eq =
fixes eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
assumes eq_equals: "eq x y \<longleftrightarrow> x = y"
begin
-lemma eq: "eq = (op =)"
+lemma eq [code unfold, code inline del]: "eq = (op =)"
by (rule ext eq_equals)+
lemma eq_refl: "eq x x \<longleftrightarrow> True"
unfolding eq by rule+
+lemma equals_eq [code inline]: "(op =) \<equiv> eq"
+ by (rule eq_reflection) (rule ext, rule ext, rule sym, rule eq_equals)
+
+declare equals_eq [symmetric, code post]
+
end
-text {* Module setup *}
+declare equals_eq [code]
+
+
+subsubsection {* Generic code generator foundation *}
+
+text {* Datatypes *}
+
+code_datatype True False
+
+code_datatype "TYPE('a\<Colon>{})"
+
+code_datatype Trueprop "prop"
+
+text {* Code equations *}
+
+lemma [code]:
+ shows "(True \<Longrightarrow> PROP P) \<equiv> PROP P"
+ and "(False \<Longrightarrow> Q) \<equiv> Trueprop True"
+ and "(PROP P \<Longrightarrow> True) \<equiv> Trueprop True"
+ and "(Q \<Longrightarrow> False) \<equiv> Trueprop (\<not> Q)" by (auto intro!: equal_intr_rule)
+
+lemma [code]:
+ shows "False \<and> x \<longleftrightarrow> False"
+ and "True \<and> x \<longleftrightarrow> x"
+ and "x \<and> False \<longleftrightarrow> False"
+ and "x \<and> True \<longleftrightarrow> x" by simp_all
+
+lemma [code]:
+ shows "False \<or> x \<longleftrightarrow> x"
+ and "True \<or> x \<longleftrightarrow> True"
+ and "x \<or> False \<longleftrightarrow> x"
+ and "x \<or> True \<longleftrightarrow> True" by simp_all
+
+lemma [code]:
+ shows "\<not> True \<longleftrightarrow> False"
+ and "\<not> False \<longleftrightarrow> True" by (rule HOL.simp_thms)+
-use "Tools/recfun_codegen.ML"
+lemmas [code] = Let_def if_True if_False
+
+lemmas [code, code unfold, symmetric, code post] = imp_conv_disj
+
+text {* Equality *}
+
+declare simp_thms(6) [code nbe]
+
+hide (open) const eq
+hide const eq
+
+setup {*
+ Code_Unit.add_const_alias @{thm equals_eq}
+*}
+
+text {* Cases *}
+
+lemma Let_case_cert:
+ assumes "CASE \<equiv> (\<lambda>x. Let x f)"
+ shows "CASE x \<equiv> f x"
+ using assms by simp_all
+
+lemma If_case_cert:
+ assumes "CASE \<equiv> (\<lambda>b. If b f g)"
+ shows "(CASE True \<equiv> f) &&& (CASE False \<equiv> g)"
+ using assms by simp_all
+
+setup {*
+ Code.add_case @{thm Let_case_cert}
+ #> Code.add_case @{thm If_case_cert}
+ #> Code.add_undefined @{const_name undefined}
+*}
+
+code_abort undefined
+
+subsubsection {* Generic code generator preprocessor *}
setup {*
- Code_ML.setup
- #> Code_Haskell.setup
- #> Nbe.setup
- #> Codegen.setup
- #> RecfunCodegen.setup
+ Code.map_pre (K HOL_basic_ss)
+ #> Code.map_post (K HOL_basic_ss)
*}
+subsubsection {* Generic code generator target languages *}
-subsection {* Nitpick hooks *}
+text {* type bool *}
+
+code_type bool
+ (SML "bool")
+ (OCaml "bool")
+ (Haskell "Bool")
+
+code_const True and False and Not and "op &" and "op |" and If
+ (SML "true" and "false" and "not"
+ and infixl 1 "andalso" and infixl 0 "orelse"
+ and "!(if (_)/ then (_)/ else (_))")
+ (OCaml "true" and "false" and "not"
+ and infixl 4 "&&" and infixl 2 "||"
+ and "!(if (_)/ then (_)/ else (_))")
+ (Haskell "True" and "False" and "not"
+ and infixl 3 "&&" and infixl 2 "||"
+ and "!(if (_)/ then (_)/ else (_))")
+
+code_reserved SML
+ bool true false not
+
+code_reserved OCaml
+ bool not
+
+text {* using built-in Haskell equality *}
+
+code_class eq
+ (Haskell "Eq")
+
+code_const "eq_class.eq"
+ (Haskell infixl 4 "==")
+
+code_const "op ="
+ (Haskell infixl 4 "==")
+
+text {* undefined *}
+
+code_const undefined
+ (SML "!(raise/ Fail/ \"undefined\")")
+ (OCaml "failwith/ \"undefined\"")
+ (Haskell "error/ \"undefined\"")
+
+subsubsection {* Evaluation and normalization by evaluation *}
+
+setup {*
+ Value.add_evaluator ("SML", Codegen.eval_term o ProofContext.theory_of)
+*}
+
+ML {*
+structure Eval_Method =
+struct
+
+val eval_ref : (unit -> bool) option ref = ref NONE;
+
+end;
+*}
+
+oracle eval_oracle = {* fn ct =>
+ let
+ val thy = Thm.theory_of_cterm ct;
+ val t = Thm.term_of ct;
+ val dummy = @{cprop True};
+ in case try HOLogic.dest_Trueprop t
+ of SOME t' => if Code_ML.eval NONE
+ ("Eval_Method.eval_ref", Eval_Method.eval_ref) (K I) thy t' []
+ then Thm.capply (Thm.capply @{cterm "op \<equiv> \<Colon> prop \<Rightarrow> prop \<Rightarrow> prop"} ct) dummy
+ else dummy
+ | NONE => dummy
+ end
+*}
+
+ML {*
+fun gen_eval_method conv ctxt = SIMPLE_METHOD'
+ (CONVERSION (Conv.params_conv (~1) (K (Conv.concl_conv (~1) conv)) ctxt)
+ THEN' rtac TrueI)
+*}
+
+method_setup eval = {* Scan.succeed (gen_eval_method eval_oracle) *}
+ "solve goal by evaluation"
+
+method_setup evaluation = {* Scan.succeed (gen_eval_method Codegen.evaluation_conv) *}
+ "solve goal by evaluation"
+
+method_setup normalization = {*
+ Scan.succeed (K (SIMPLE_METHOD' (CONVERSION Nbe.norm_conv THEN' (fn k => TRY (rtac TrueI k)))))
+*} "solve goal by normalization"
+
+subsubsection {* Quickcheck *}
+
+setup {*
+ Quickcheck.add_generator ("SML", Codegen.test_term)
+*}
+
+quickcheck_params [size = 5, iterations = 50]
+
+
+subsection {* Nitpick setup *}
text {* This will be relocated once Nitpick is moved to HOL. *}
@@ -1730,10 +1998,14 @@
val description = "introduction rules for (co)inductive predicates as needed by Nitpick"
)
*}
-setup {* Nitpick_Const_Def_Thms.setup
- #> Nitpick_Const_Simp_Thms.setup
- #> Nitpick_Const_Psimp_Thms.setup
- #> Nitpick_Ind_Intro_Thms.setup *}
+
+setup {*
+ Nitpick_Const_Def_Thms.setup
+ #> Nitpick_Const_Simp_Thms.setup
+ #> Nitpick_Const_Psimp_Thms.setup
+ #> Nitpick_Ind_Intro_Thms.setup
+*}
+
subsection {* Legacy tactics and ML bindings *}
--- a/src/HOL/HoareParallel/Graph.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/HoareParallel/Graph.thy Mon May 11 17:20:52 2009 +0200
@@ -172,9 +172,9 @@
prefer 2 apply arith
apply(drule_tac n = "Suc nata" in Compl_lemma)
apply clarify
- using [[fast_arith_split_limit = 0]]
+ using [[linarith_split_limit = 0]]
apply force
- using [[fast_arith_split_limit = 9]]
+ using [[linarith_split_limit = 9]]
apply(drule leI)
apply(subgoal_tac "Suc (length path - Suc m + nata)=(length path - Suc 0) - (m - Suc nata)")
apply(erule_tac x = "m - (Suc nata)" in allE)
--- a/src/HOL/HoareParallel/OG_Tran.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/HoareParallel/OG_Tran.thy Mon May 11 17:20:52 2009 +0200
@@ -74,7 +74,7 @@
abbreviation
ann_transition_n :: "('a ann_com_op \<times> 'a) \<Rightarrow> nat \<Rightarrow> ('a ann_com_op \<times> 'a)
\<Rightarrow> bool" ("_ -_\<rightarrow> _"[81,81] 100) where
- "con_0 -n\<rightarrow> con_1 \<equiv> (con_0, con_1) \<in> ann_transition^n"
+ "con_0 -n\<rightarrow> con_1 \<equiv> (con_0, con_1) \<in> ann_transition ^^ n"
abbreviation
ann_transitions :: "('a ann_com_op \<times> 'a) \<Rightarrow> ('a ann_com_op \<times> 'a) \<Rightarrow> bool"
@@ -84,7 +84,7 @@
abbreviation
transition_n :: "('a com \<times> 'a) \<Rightarrow> nat \<Rightarrow> ('a com \<times> 'a) \<Rightarrow> bool"
("_ -P_\<rightarrow> _"[81,81,81] 100) where
- "con_0 -Pn\<rightarrow> con_1 \<equiv> (con_0, con_1) \<in> transition^n"
+ "con_0 -Pn\<rightarrow> con_1 \<equiv> (con_0, con_1) \<in> transition ^^ n"
subsection {* Definition of Semantics *}
--- a/src/HOL/IMP/Compiler0.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/IMP/Compiler0.thy Mon May 11 17:20:52 2009 +0200
@@ -45,7 +45,7 @@
abbreviation
stepan :: "[instr list,state,nat,nat,state,nat] \<Rightarrow> bool"
("_ \<turnstile>/ (3\<langle>_,_\<rangle>/ -(_)\<rightarrow> \<langle>_,_\<rangle>)" [50,0,0,0,0,0] 50) where
- "P \<turnstile> \<langle>s,m\<rangle> -(i)\<rightarrow> \<langle>t,n\<rangle> == ((s,m),t,n) : ((stepa1 P)^i)"
+ "P \<turnstile> \<langle>s,m\<rangle> -(i)\<rightarrow> \<langle>t,n\<rangle> == ((s,m),t,n) : (stepa1 P ^^ i)"
subsection "The compiler"
--- a/src/HOL/IMP/Machines.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/IMP/Machines.thy Mon May 11 17:20:52 2009 +0200
@@ -1,7 +1,6 @@
-
-(* $Id$ *)
-
-theory Machines imports Natural begin
+theory Machines
+imports Natural
+begin
lemma rtrancl_eq: "R^* = Id \<union> (R O R^*)"
by (fast intro: rtrancl_into_rtrancl elim: rtranclE)
@@ -11,20 +10,22 @@
lemmas converse_rel_powE = rel_pow_E2
-lemma R_O_Rn_commute: "R O R^n = R^n O R"
+lemma R_O_Rn_commute: "R O R ^^ n = R ^^ n O R"
by (induct n) (simp, simp add: O_assoc [symmetric])
lemma converse_in_rel_pow_eq:
- "((x,z) \<in> R^n) = (n=0 \<and> z=x \<or> (\<exists>m y. n = Suc m \<and> (x,y) \<in> R \<and> (y,z) \<in> R^m))"
+ "((x,z) \<in> R ^^ n) = (n=0 \<and> z=x \<or> (\<exists>m y. n = Suc m \<and> (x,y) \<in> R \<and> (y,z) \<in> R ^^ m))"
apply(rule iffI)
apply(blast elim:converse_rel_powE)
apply (fastsimp simp add:gr0_conv_Suc R_O_Rn_commute)
done
-lemma rel_pow_plus: "R^(m+n) = R^n O R^m"
+lemma rel_pow_plus:
+ "R ^^ (m+n) = R ^^ n O R ^^ m"
by (induct n) (simp, simp add: O_assoc)
-lemma rel_pow_plusI: "\<lbrakk> (x,y) \<in> R^m; (y,z) \<in> R^n \<rbrakk> \<Longrightarrow> (x,z) \<in> R^(m+n)"
+lemma rel_pow_plusI:
+ "\<lbrakk> (x,y) \<in> R ^^ m; (y,z) \<in> R ^^ n \<rbrakk> \<Longrightarrow> (x,z) \<in> R ^^ (m+n)"
by (simp add: rel_pow_plus rel_compI)
subsection "Instructions"
@@ -57,7 +58,7 @@
abbreviation
exec0n :: "[instrs, nat,state, nat, nat,state] \<Rightarrow> bool"
("(_/ \<turnstile> (1\<langle>_,/_\<rangle>)/ -_\<rightarrow> (1\<langle>_,/_\<rangle>))" [50,0,0,0,0] 50) where
- "p \<turnstile> \<langle>i,s\<rangle> -n\<rightarrow> \<langle>j,t\<rangle> == ((i,s),j,t) : (exec01 p)^n"
+ "p \<turnstile> \<langle>i,s\<rangle> -n\<rightarrow> \<langle>j,t\<rangle> == ((i,s),j,t) : (exec01 p)^^n"
subsection "M0 with lists"
@@ -89,7 +90,7 @@
abbreviation
stepan :: "[instrs,instrs,state, nat, instrs,instrs,state] \<Rightarrow> bool"
("((1\<langle>_,/_,/_\<rangle>)/ -_\<rightarrow> (1\<langle>_,/_,/_\<rangle>))" 50) where
- "\<langle>p,q,s\<rangle> -i\<rightarrow> \<langle>p',q',t\<rangle> == ((p,q,s),p',q',t) : (stepa1^i)"
+ "\<langle>p,q,s\<rangle> -i\<rightarrow> \<langle>p',q',t\<rangle> == ((p,q,s),p',q',t) : (stepa1^^i)"
inductive_cases execE: "((i#is,p,s), (is',p',s')) : stepa1"
--- a/src/HOL/IMP/Transition.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/IMP/Transition.thy Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title: HOL/IMP/Transition.thy
- ID: $Id$
Author: Tobias Nipkow & Robert Sandner, TUM
Isar Version: Gerwin Klein, 2001
Copyright 1996 TUM
@@ -69,7 +68,7 @@
abbreviation
evalcn :: "[(com option\<times>state),nat,(com option\<times>state)] \<Rightarrow> bool"
("_ -_\<rightarrow>\<^sub>1 _" [60,60,60] 60) where
- "cs -n\<rightarrow>\<^sub>1 cs' == (cs,cs') \<in> evalc1^n"
+ "cs -n\<rightarrow>\<^sub>1 cs' == (cs,cs') \<in> evalc1^^n"
abbreviation
evalc' :: "[(com option\<times>state),(com option\<times>state)] \<Rightarrow> bool"
@@ -77,28 +76,9 @@
"cs \<longrightarrow>\<^sub>1\<^sup>* cs' == (cs,cs') \<in> evalc1^*"
(*<*)
-(* fixme: move to Relation_Power.thy *)
-lemma rel_pow_Suc_E2 [elim!]:
- "[| (x, z) \<in> R ^ Suc n; !!y. [| (x, y) \<in> R; (y, z) \<in> R ^ n |] ==> P |] ==> P"
- by (blast dest: rel_pow_Suc_D2)
+declare rel_pow_Suc_E2 [elim!]
+(*>*)
-lemma rtrancl_imp_rel_pow: "p \<in> R^* \<Longrightarrow> \<exists>n. p \<in> R^n"
-proof (induct p)
- fix x y
- assume "(x, y) \<in> R\<^sup>*"
- thus "\<exists>n. (x, y) \<in> R^n"
- proof induct
- fix a have "(a, a) \<in> R^0" by simp
- thus "\<exists>n. (a, a) \<in> R ^ n" ..
- next
- fix a b c assume "\<exists>n. (a, b) \<in> R ^ n"
- then obtain n where "(a, b) \<in> R^n" ..
- moreover assume "(b, c) \<in> R"
- ultimately have "(a, c) \<in> R^(Suc n)" by auto
- thus "\<exists>n. (a, c) \<in> R^n" ..
- qed
-qed
-(*>*)
text {*
As for the big step semantics you can read these rules in a
syntax directed way:
@@ -189,8 +169,8 @@
(*<*)
(* FIXME: relpow.simps don't work *)
lemmas [simp del] = relpow.simps
-lemma rel_pow_0 [simp]: "!!R::('a*'a) set. R^0 = Id" by (simp add: relpow.simps)
-lemma rel_pow_Suc_0 [simp]: "!!R::('a*'a) set. R^(Suc 0) = R" by (simp add: relpow.simps)
+lemma rel_pow_0 [simp]: "!!R::('a*'a) set. R ^^ 0 = Id" by (simp add: relpow.simps)
+lemma rel_pow_Suc_0 [simp]: "!!R::('a*'a) set. R ^^ Suc 0 = R" by (simp add: relpow.simps)
(*>*)
lemma evalc1_None_0 [simp]: "\<langle>s\<rangle> -n\<rightarrow>\<^sub>1 y = (n = 0 \<and> y = \<langle>s\<rangle>)"
--- a/src/HOL/Imperative_HOL/Heap_Monad.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Imperative_HOL/Heap_Monad.thy Mon May 11 17:20:52 2009 +0200
@@ -317,7 +317,7 @@
val dummy_type = ITyVar dummy_name;
val dummy_case_term = IVar dummy_name;
(*assumption: dummy values are not relevant for serialization*)
- val unitt = IConst (unit', ([], []));
+ val unitt = IConst (unit', (([], []), []));
fun dest_abs ((v, ty) `|-> t, _) = ((v, ty), t)
| dest_abs (t, ty) =
let
@@ -353,10 +353,10 @@
| imp_monad_bind bind' return' unit' (ICase (((t, ty), pats), t0)) = ICase
(((imp_monad_bind bind' return' unit' t, ty), (map o pairself) (imp_monad_bind bind' return' unit') pats), imp_monad_bind bind' return' unit' t0);
- fun imp_program naming = (Graph.map_nodes o map_terms_stmt)
- (imp_monad_bind (lookup naming @{const_name bindM})
- (lookup naming @{const_name return})
- (lookup naming @{const_name Unity}));
+ fun imp_program naming = (Graph.map_nodes o map_terms_stmt)
+ (imp_monad_bind (lookup naming @{const_name bindM})
+ (lookup naming @{const_name return})
+ (lookup naming @{const_name Unity}));
in
--- a/src/HOL/Import/HOL/HOL4Base.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Import/HOL/HOL4Base.thy Mon May 11 17:20:52 2009 +0200
@@ -2794,8 +2794,8 @@
by (import numeral numeral_fact)
lemma numeral_funpow: "ALL n::nat.
- ((f::'a::type => 'a::type) ^ n) (x::'a::type) =
- (if n = 0 then x else (f ^ (n - 1)) (f x))"
+ ((f::'a::type => 'a::type) ^^ n) (x::'a::type) =
+ (if n = 0 then x else (f ^^ (n - 1)) (f x))"
by (import numeral numeral_funpow)
;end_setup
--- a/src/HOL/Import/HOL/HOL4Word32.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Import/HOL/HOL4Word32.thy Mon May 11 17:20:52 2009 +0200
@@ -434,15 +434,15 @@
by (import word32 EQUIV_QT)
lemma FUNPOW_THM: "ALL (f::'a::type => 'a::type) (n::nat) x::'a::type.
- (f ^ n) (f x) = f ((f ^ n) x)"
+ (f ^^ n) (f x) = f ((f ^^ n) x)"
by (import word32 FUNPOW_THM)
lemma FUNPOW_THM2: "ALL (f::'a::type => 'a::type) (n::nat) x::'a::type.
- (f ^ Suc n) x = f ((f ^ n) x)"
+ (f ^^ Suc n) x = f ((f ^^ n) x)"
by (import word32 FUNPOW_THM2)
lemma FUNPOW_COMP: "ALL (f::'a::type => 'a::type) (m::nat) (n::nat) a::'a::type.
- (f ^ m) ((f ^ n) a) = (f ^ (m + n)) a"
+ (f ^^ m) ((f ^^ n) a) = (f ^^ (m + n)) a"
by (import word32 FUNPOW_COMP)
lemma INw_MODw: "ALL n::nat. INw (MODw n)"
@@ -1170,23 +1170,23 @@
constdefs
word_lsr :: "word32 => nat => word32"
- "word_lsr == %(a::word32) n::nat. (word_lsr1 ^ n) a"
+ "word_lsr == %(a::word32) n::nat. (word_lsr1 ^^ n) a"
-lemma word_lsr: "ALL (a::word32) n::nat. word_lsr a n = (word_lsr1 ^ n) a"
+lemma word_lsr: "ALL (a::word32) n::nat. word_lsr a n = (word_lsr1 ^^ n) a"
by (import word32 word_lsr)
constdefs
word_asr :: "word32 => nat => word32"
- "word_asr == %(a::word32) n::nat. (word_asr1 ^ n) a"
+ "word_asr == %(a::word32) n::nat. (word_asr1 ^^ n) a"
-lemma word_asr: "ALL (a::word32) n::nat. word_asr a n = (word_asr1 ^ n) a"
+lemma word_asr: "ALL (a::word32) n::nat. word_asr a n = (word_asr1 ^^ n) a"
by (import word32 word_asr)
constdefs
word_ror :: "word32 => nat => word32"
- "word_ror == %(a::word32) n::nat. (word_ror1 ^ n) a"
+ "word_ror == %(a::word32) n::nat. (word_ror1 ^^ n) a"
-lemma word_ror: "ALL (a::word32) n::nat. word_ror a n = (word_ror1 ^ n) a"
+lemma word_ror: "ALL (a::word32) n::nat. word_ror a n = (word_ror1 ^^ n) a"
by (import word32 word_ror)
consts
@@ -1583,4 +1583,3 @@
;end_setup
end
-
--- a/src/HOL/Import/HOL/arithmetic.imp Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Import/HOL/arithmetic.imp Mon May 11 17:20:52 2009 +0200
@@ -43,7 +43,7 @@
"TWO" > "HOL4Base.arithmetic.TWO"
"TIMES2" > "NatSimprocs.nat_mult_2"
"SUC_SUB1" > "HOL4Base.arithmetic.SUC_SUB1"
- "SUC_ONE_ADD" > "NatBin.Suc_eq_add_numeral_1_left"
+ "SUC_ONE_ADD" > "Nat_Numeral.Suc_eq_add_numeral_1_left"
"SUC_NOT" > "Nat.nat.simps_2"
"SUC_ELIM_THM" > "HOL4Base.arithmetic.SUC_ELIM_THM"
"SUC_ADD_SYM" > "HOL4Base.arithmetic.SUC_ADD_SYM"
@@ -233,7 +233,7 @@
"EVEN_AND_ODD" > "HOL4Base.arithmetic.EVEN_AND_ODD"
"EVEN_ADD" > "HOL4Base.arithmetic.EVEN_ADD"
"EVEN" > "HOL4Base.arithmetic.EVEN"
- "EQ_MULT_LCANCEL" > "NatBin.nat_mult_eq_cancel_disj"
+ "EQ_MULT_LCANCEL" > "Nat_Numeral.nat_mult_eq_cancel_disj"
"EQ_MONO_ADD_EQ" > "Nat.nat_add_right_cancel"
"EQ_LESS_EQ" > "Orderings.order_eq_iff"
"EQ_ADD_RCANCEL" > "Nat.nat_add_right_cancel"
--- a/src/HOL/Import/HOL/real.imp Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Import/HOL/real.imp Mon May 11 17:20:52 2009 +0200
@@ -99,7 +99,7 @@
"REAL_POW_INV" > "Power.power_inverse"
"REAL_POW_DIV" > "Power.power_divide"
"REAL_POW_ADD" > "Power.power_add"
- "REAL_POW2_ABS" > "NatBin.power2_abs"
+ "REAL_POW2_ABS" > "Nat_Numeral.power2_abs"
"REAL_POS_NZ" > "HOL4Real.real.REAL_POS_NZ"
"REAL_POS" > "RealDef.real_of_nat_ge_zero"
"REAL_POASQ" > "HOL4Real.real.REAL_POASQ"
@@ -210,7 +210,7 @@
"REAL_LE_RDIV_EQ" > "Ring_and_Field.pos_le_divide_eq"
"REAL_LE_RDIV" > "Ring_and_Field.mult_imp_le_div_pos"
"REAL_LE_RADD" > "OrderedGroup.add_le_cancel_right"
- "REAL_LE_POW2" > "NatBin.zero_compare_simps_12"
+ "REAL_LE_POW2" > "Nat_Numeral.zero_compare_simps_12"
"REAL_LE_NEGTOTAL" > "HOL4Real.real.REAL_LE_NEGTOTAL"
"REAL_LE_NEGR" > "OrderedGroup.le_minus_self_iff"
"REAL_LE_NEGL" > "OrderedGroup.minus_le_self_iff"
@@ -313,7 +313,7 @@
"POW_ONE" > "Power.power_one"
"POW_NZ" > "Power.field_power_not_zero"
"POW_MUL" > "Power.power_mult_distrib"
- "POW_MINUS1" > "NatBin.power_minus1_even"
+ "POW_MINUS1" > "Nat_Numeral.power_minus1_even"
"POW_M1" > "HOL4Real.real.POW_M1"
"POW_LT" > "HOL4Real.real.POW_LT"
"POW_LE" > "Power.power_mono"
@@ -323,7 +323,7 @@
"POW_ABS" > "Power.power_abs"
"POW_2_LT" > "RealPow.two_realpow_gt"
"POW_2_LE1" > "RealPow.two_realpow_ge_one"
- "POW_2" > "NatBin.power2_eq_square"
+ "POW_2" > "Nat_Numeral.power2_eq_square"
"POW_1" > "Power.power_one_right"
"POW_0" > "Power.power_0_Suc"
"ABS_ZERO" > "OrderedGroup.abs_eq_0"
@@ -335,7 +335,7 @@
"ABS_SIGN2" > "HOL4Real.real.ABS_SIGN2"
"ABS_SIGN" > "HOL4Real.real.ABS_SIGN"
"ABS_REFL" > "HOL4Real.real.ABS_REFL"
- "ABS_POW2" > "NatBin.abs_power2"
+ "ABS_POW2" > "Nat_Numeral.abs_power2"
"ABS_POS" > "OrderedGroup.abs_ge_zero"
"ABS_NZ" > "OrderedGroup.zero_less_abs_iff"
"ABS_NEG" > "OrderedGroup.abs_minus_cancel"
--- a/src/HOL/Import/HOL4Compat.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Import/HOL4Compat.thy Mon May 11 17:20:52 2009 +0200
@@ -202,19 +202,13 @@
constdefs
FUNPOW :: "('a => 'a) => nat => 'a => 'a"
- "FUNPOW f n == f ^ n"
+ "FUNPOW f n == f ^^ n"
-lemma FUNPOW: "(ALL f x. (f ^ 0) x = x) &
- (ALL f n x. (f ^ Suc n) x = (f ^ n) (f x))"
-proof auto
- fix f n x
- have "ALL x. f ((f ^ n) x) = (f ^ n) (f x)"
- by (induct n,auto)
- thus "f ((f ^ n) x) = (f ^ n) (f x)"
- ..
-qed
+lemma FUNPOW: "(ALL f x. (f ^^ 0) x = x) &
+ (ALL f n x. (f ^^ Suc n) x = (f ^^ n) (f x))"
+ by (simp add: funpow_swap1)
-lemma [hol4rew]: "FUNPOW f n = f ^ n"
+lemma [hol4rew]: "FUNPOW f n = f ^^ n"
by (simp add: FUNPOW_def)
lemma ADD: "(!n. (0::nat) + n = n) & (!m n. Suc m + n = Suc (m + n))"
@@ -224,7 +218,7 @@
by simp
lemma SUB: "(!m. (0::nat) - m = 0) & (!m n. (Suc m) - n = (if m < n then 0 else Suc (m - n)))"
- by (simp, arith)
+ by (simp) arith
lemma MAX_DEF: "max (m::nat) n = (if m < n then n else m)"
by (simp add: max_def)
--- a/src/HOL/Import/HOLLight/hollight.imp Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Import/HOLLight/hollight.imp Mon May 11 17:20:52 2009 +0200
@@ -1515,7 +1515,7 @@
"EQ_REFL_T" > "HOL.simp_thms_6"
"EQ_REFL" > "Presburger.fm_modd_pinf"
"EQ_MULT_RCANCEL" > "Nat.mult_cancel2"
- "EQ_MULT_LCANCEL" > "NatBin.nat_mult_eq_cancel_disj"
+ "EQ_MULT_LCANCEL" > "Nat_Numeral.nat_mult_eq_cancel_disj"
"EQ_IMP_LE" > "HOLLight.hollight.EQ_IMP_LE"
"EQ_EXT" > "HOL.meta_eq_to_obj_eq"
"EQ_CLAUSES" > "HOLLight.hollight.EQ_CLAUSES"
--- a/src/HOL/Int.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Int.thy Mon May 11 17:20:52 2009 +0200
@@ -12,10 +12,13 @@
uses
("Tools/numeral.ML")
("Tools/numeral_syntax.ML")
+ ("Tools/int_arith.ML")
"~~/src/Provers/Arith/assoc_fold.ML"
"~~/src/Provers/Arith/cancel_numerals.ML"
"~~/src/Provers/Arith/combine_numerals.ML"
- ("Tools/int_arith.ML")
+ "~~/src/Provers/Arith/cancel_numeral_factor.ML"
+ "~~/src/Provers/Arith/extract_common_term.ML"
+ ("Tools/numeral_simprocs.ML")
begin
subsection {* The equivalence relation underlying the integers *}
@@ -292,9 +295,7 @@
context ring_1
begin
-definition
- of_int :: "int \<Rightarrow> 'a"
-where
+definition of_int :: "int \<Rightarrow> 'a" where
[code del]: "of_int z = contents (\<Union>(i, j) \<in> Rep_Integ z. { of_nat i - of_nat j })"
lemma of_int: "of_int (Abs_Integ (intrel `` {(i,j)})) = of_nat i - of_nat j"
@@ -330,6 +331,10 @@
lemma of_int_of_nat_eq [simp]: "of_int (of_nat n) = of_nat n"
by (induct n) auto
+lemma of_int_power:
+ "of_int (z ^ n) = of_int z ^ n"
+ by (induct n) simp_all
+
end
context ordered_idom
@@ -1266,14 +1271,9 @@
definition Ints :: "'a set" where
[code del]: "Ints = range of_int"
-end
-
notation (xsymbols)
Ints ("\<int>")
-context ring_1
-begin
-
lemma Ints_0 [simp]: "0 \<in> \<int>"
apply (simp add: Ints_def)
apply (rule range_eqI)
@@ -1518,9 +1518,18 @@
of_nat_0 of_nat_1 of_nat_Suc of_nat_add of_nat_mult
of_int_0 of_int_1 of_int_add of_int_mult
+use "Tools/numeral_simprocs.ML"
+
use "Tools/int_arith.ML"
declaration {* K Int_Arith.setup *}
+setup {*
+ ReorientProc.add
+ (fn Const (@{const_name number_of}, _) $ _ => true | _ => false)
+*}
+
+simproc_setup reorient_numeral ("number_of w = x") = ReorientProc.proc
+
subsection{*Lemmas About Small Numerals*}
@@ -1536,7 +1545,7 @@
by (simp add: abs_if)
lemma abs_power_minus_one [simp]:
- "abs(-1 ^ n) = (1::'a::{ordered_idom,number_ring,recpower})"
+ "abs(-1 ^ n) = (1::'a::{ordered_idom,number_ring})"
by (simp add: power_abs)
lemma of_int_number_of_eq [simp]:
@@ -1846,49 +1855,6 @@
qed
-subsection {* Integer Powers *}
-
-instantiation int :: recpower
-begin
-
-primrec power_int where
- "p ^ 0 = (1\<Colon>int)"
- | "p ^ (Suc n) = (p\<Colon>int) * (p ^ n)"
-
-instance proof
- fix z :: int
- fix n :: nat
- show "z ^ 0 = 1" by simp
- show "z ^ Suc n = z * (z ^ n)" by simp
-qed
-
-declare power_int.simps [simp del]
-
-end
-
-lemma zpower_zadd_distrib: "x ^ (y + z) = ((x ^ y) * (x ^ z)::int)"
- by (rule Power.power_add)
-
-lemma zpower_zpower: "(x ^ y) ^ z = (x ^ (y * z)::int)"
- by (rule Power.power_mult [symmetric])
-
-lemma zero_less_zpower_abs_iff [simp]:
- "(0 < abs x ^ n) \<longleftrightarrow> (x \<noteq> (0::int) | n = 0)"
- by (induct n) (auto simp add: zero_less_mult_iff)
-
-lemma zero_le_zpower_abs [simp]: "(0::int) \<le> abs x ^ n"
- by (induct n) (auto simp add: zero_le_mult_iff)
-
-lemma of_int_power:
- "of_int (z ^ n) = (of_int z ^ n :: 'a::{recpower, ring_1})"
- by (induct n) simp_all
-
-lemma int_power: "int (m^n) = (int m) ^ n"
- by (rule of_nat_power)
-
-lemmas zpower_int = int_power [symmetric]
-
-
subsection {* Further theorems on numerals *}
subsubsection{*Special Simplification for Constants*}
@@ -2278,4 +2244,25 @@
lemmas zless_le = less_int_def
lemmas int_eq_of_nat = TrueI
+lemma zpower_zadd_distrib:
+ "x ^ (y + z) = ((x ^ y) * (x ^ z)::int)"
+ by (rule power_add)
+
+lemma zero_less_zpower_abs_iff:
+ "(0 < abs x ^ n) \<longleftrightarrow> (x \<noteq> (0::int) | n = 0)"
+ by (rule zero_less_power_abs_iff)
+
+lemma zero_le_zpower_abs: "(0::int) \<le> abs x ^ n"
+ by (rule zero_le_power_abs)
+
+lemma zpower_zpower:
+ "(x ^ y) ^ z = (x ^ (y * z)::int)"
+ by (rule power_mult [symmetric])
+
+lemma int_power:
+ "int (m ^ n) = int m ^ n"
+ by (rule of_nat_power)
+
+lemmas zpower_int = int_power [symmetric]
+
end
--- a/src/HOL/IntDiv.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/IntDiv.thy Mon May 11 17:20:52 2009 +0200
@@ -8,10 +8,6 @@
theory IntDiv
imports Int Divides FunDef
-uses
- "~~/src/Provers/Arith/cancel_numeral_factor.ML"
- "~~/src/Provers/Arith/extract_common_term.ML"
- ("Tools/int_factor_simprocs.ML")
begin
definition divmod_rel :: "int \<Rightarrow> int \<Rightarrow> int \<times> int \<Rightarrow> bool" where
@@ -249,33 +245,33 @@
text {* Tool setup *}
ML {*
-local
+local
-structure CancelDivMod = CancelDivModFun(
-struct
- val div_name = @{const_name Divides.div};
- val mod_name = @{const_name Divides.mod};
+structure CancelDivMod = CancelDivModFun(struct
+
+ val div_name = @{const_name div};
+ val mod_name = @{const_name mod};
val mk_binop = HOLogic.mk_binop;
- val mk_sum = Int_Numeral_Simprocs.mk_sum HOLogic.intT;
- val dest_sum = Int_Numeral_Simprocs.dest_sum;
- val div_mod_eqs =
- map mk_meta_eq [@{thm zdiv_zmod_equality},
- @{thm zdiv_zmod_equality2}];
+ val mk_sum = Numeral_Simprocs.mk_sum HOLogic.intT;
+ val dest_sum = Numeral_Simprocs.dest_sum;
+
+ val div_mod_eqs = map mk_meta_eq [@{thm zdiv_zmod_equality}, @{thm zdiv_zmod_equality2}];
+
val trans = trans;
- val prove_eq_sums =
- let
- val simps = @{thm diff_int_def} :: Int_Numeral_Simprocs.add_0s @ @{thms zadd_ac}
- in Arith_Data.prove_conv2 all_tac (Arith_Data.simp_all_tac simps) end;
+
+ val prove_eq_sums = Arith_Data.prove_conv2 all_tac (Arith_Data.simp_all_tac
+ (@{thm diff_minus} :: @{thms add_0s} @ @{thms add_ac}))
+
end)
in
-val cancel_zdiv_zmod_proc = Simplifier.simproc (the_context ())
- "cancel_zdiv_zmod" ["(m::int) + n"] (K CancelDivMod.proc)
+val cancel_div_mod_int_proc = Simplifier.simproc (the_context ())
+ "cancel_zdiv_zmod" ["(k::int) + l"] (K CancelDivMod.proc);
-end;
+val _ = Addsimprocs [cancel_div_mod_int_proc];
-Addsimprocs [cancel_zdiv_zmod_proc]
+end
*}
lemma pos_mod_conj : "(0::int) < b ==> 0 \<le> a mod b & a mod b < b"
@@ -711,6 +707,25 @@
show "(a + c * b) div b = c + a div b"
unfolding zdiv_zadd1_eq [of a "c * b"] using not0
by (simp add: zmod_zmult1_eq zmod_zdiv_trivial zdiv_zmult1_eq)
+next
+ fix a b c :: int
+ assume "a \<noteq> 0"
+ then show "(a * b) div (a * c) = b div c"
+ proof (cases "b \<noteq> 0 \<and> c \<noteq> 0")
+ case False then show ?thesis by auto
+ next
+ case True then have "b \<noteq> 0" and "c \<noteq> 0" by auto
+ with `a \<noteq> 0`
+ have "\<And>q r. divmod_rel b c (q, r) \<Longrightarrow> divmod_rel (a * b) (a * c) (q, a * r)"
+ apply (auto simp add: divmod_rel_def)
+ apply (auto simp add: algebra_simps)
+ apply (auto simp add: zero_less_mult_iff zero_le_mult_iff mult_le_0_iff)
+ done
+ moreover with `c \<noteq> 0` divmod_rel_div_mod have "divmod_rel b c (b div c, b mod c)" by auto
+ ultimately have "divmod_rel (a * b) (a * c) (b div c, a * (b mod c))" .
+ moreover from `a \<noteq> 0` `c \<noteq> 0` have "a * c \<noteq> 0" by simp
+ ultimately show ?thesis by (rule divmod_rel_div)
+ qed
qed auto
lemma posDivAlg_div_mod:
@@ -808,52 +823,6 @@
done
-subsection{*Cancellation of Common Factors in div*}
-
-lemma zdiv_zmult_zmult1_aux1:
- "[| (0::int) < b; c \<noteq> 0 |] ==> (c*a) div (c*b) = a div b"
-by (subst zdiv_zmult2_eq, auto)
-
-lemma zdiv_zmult_zmult1_aux2:
- "[| b < (0::int); c \<noteq> 0 |] ==> (c*a) div (c*b) = a div b"
-apply (subgoal_tac " (c * (-a)) div (c * (-b)) = (-a) div (-b) ")
-apply (rule_tac [2] zdiv_zmult_zmult1_aux1, auto)
-done
-
-lemma zdiv_zmult_zmult1: "c \<noteq> (0::int) ==> (c*a) div (c*b) = a div b"
-apply (case_tac "b = 0", simp)
-apply (auto simp add: linorder_neq_iff zdiv_zmult_zmult1_aux1 zdiv_zmult_zmult1_aux2)
-done
-
-lemma zdiv_zmult_zmult1_if[simp]:
- "(k*m) div (k*n) = (if k = (0::int) then 0 else m div n)"
-by (simp add:zdiv_zmult_zmult1)
-
-
-subsection{*Distribution of Factors over mod*}
-
-lemma zmod_zmult_zmult1_aux1:
- "[| (0::int) < b; c \<noteq> 0 |] ==> (c*a) mod (c*b) = c * (a mod b)"
-by (subst zmod_zmult2_eq, auto)
-
-lemma zmod_zmult_zmult1_aux2:
- "[| b < (0::int); c \<noteq> 0 |] ==> (c*a) mod (c*b) = c * (a mod b)"
-apply (subgoal_tac " (c * (-a)) mod (c * (-b)) = c * ((-a) mod (-b))")
-apply (rule_tac [2] zmod_zmult_zmult1_aux1, auto)
-done
-
-lemma zmod_zmult_zmult1: "(c*a) mod (c*b) = (c::int) * (a mod b)"
-apply (case_tac "b = 0", simp)
-apply (case_tac "c = 0", simp)
-apply (auto simp add: linorder_neq_iff zmod_zmult_zmult1_aux1 zmod_zmult_zmult1_aux2)
-done
-
-lemma zmod_zmult_zmult2: "(a*c) mod (b*c) = (a mod b) * (c::int)"
-apply (cut_tac c = c in zmod_zmult_zmult1)
-apply (auto simp add: mult_commute)
-done
-
-
subsection {*Splitting Rules for div and mod*}
text{*The proofs of the two lemmas below are essentially identical*}
@@ -937,7 +906,7 @@
right_distrib)
thus ?thesis
by (subst zdiv_zadd1_eq,
- simp add: zdiv_zmult_zmult1 zmod_zmult_zmult1 one_less_a2
+ simp add: mod_mult_mult1 one_less_a2
div_pos_pos_trivial)
qed
@@ -961,7 +930,7 @@
then number_of v div (number_of w)
else (number_of v + (1::int)) div (number_of w))"
apply (simp only: number_of_eq numeral_simps UNIV_I split: split_if)
-apply (simp add: zdiv_zmult_zmult1 pos_zdiv_mult_2 neg_zdiv_mult_2 add_ac)
+apply (simp add: pos_zdiv_mult_2 neg_zdiv_mult_2 add_ac)
done
@@ -977,7 +946,7 @@
apply (auto simp add: add_commute [of 1] mult_commute add1_zle_eq
pos_mod_bound)
apply (subst mod_add_eq)
-apply (simp add: zmod_zmult_zmult2 mod_pos_pos_trivial)
+apply (simp add: mod_mult_mult2 mod_pos_pos_trivial)
apply (rule mod_pos_pos_trivial)
apply (auto simp add: mod_pos_pos_trivial ring_distribs)
apply (subgoal_tac "0 \<le> b mod a", arith, simp)
@@ -998,7 +967,7 @@
"number_of (Int.Bit0 v) mod number_of (Int.Bit0 w) =
(2::int) * (number_of v mod number_of w)"
apply (simp only: number_of_eq numeral_simps)
-apply (simp add: zmod_zmult_zmult1 pos_zmod_mult_2
+apply (simp add: mod_mult_mult1 pos_zmod_mult_2
neg_zmod_mult_2 add_ac)
done
@@ -1008,7 +977,7 @@
then 2 * (number_of v mod number_of w) + 1
else 2 * ((number_of v + (1::int)) mod number_of w) - 1)"
apply (simp only: number_of_eq numeral_simps)
-apply (simp add: zmod_zmult_zmult1 pos_zmod_mult_2
+apply (simp add: mod_mult_mult1 pos_zmod_mult_2
neg_zmod_mult_2 add_ac)
done
@@ -1090,9 +1059,7 @@
done
lemma zdvd_zmod: "f dvd m ==> f dvd (n::int) ==> f dvd m mod n"
- apply (simp add: dvd_def)
- apply (auto simp add: zmod_zmult_zmult1)
- done
+ by (auto elim!: dvdE simp add: mod_mult_mult1)
lemma zdvd_zmod_imp_zdvd: "k dvd m mod n ==> k dvd n ==> k dvd (m::int)"
apply (subgoal_tac "k dvd n * (m div n) + m mod n")
@@ -1106,8 +1073,6 @@
prefer 2
apply (blast intro: order_less_trans)
apply (simp add: zero_less_mult_iff)
- apply (subgoal_tac "n * k < n * 1")
- apply (drule mult_less_cancel_left [THEN iffD1], auto)
done
lemma zmult_div_cancel: "(n::int) * (m div n) = m - (m mod n)"
@@ -1247,9 +1212,9 @@
lemmas zmod_simps =
mod_add_left_eq [symmetric]
mod_add_right_eq [symmetric]
- IntDiv.zmod_zmult1_eq [symmetric]
- mod_mult_left_eq [symmetric]
- IntDiv.zpower_zmod
+ zmod_zmult1_eq [symmetric]
+ mod_mult_left_eq [symmetric]
+ zpower_zmod
zminus_zmod zdiff_zmod_left zdiff_zmod_right
text {* Distributive laws for function @{text nat}. *}
@@ -1362,11 +1327,6 @@
qed
-subsection {* Simproc setup *}
-
-use "Tools/int_factor_simprocs.ML"
-
-
subsection {* Code generation *}
definition pdivmod :: "int \<Rightarrow> int \<Rightarrow> int \<times> int" where
--- a/src/HOL/IsaMakefile Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/IsaMakefile Mon May 11 17:20:52 2009 +0200
@@ -89,10 +89,9 @@
$(SRC)/Tools/IsaPlanner/rw_tools.ML \
$(SRC)/Tools/IsaPlanner/zipper.ML \
$(SRC)/Tools/atomize_elim.ML \
- $(SRC)/Tools/code/code_funcgr.ML \
+ $(SRC)/Tools/auto_solve.ML \
$(SRC)/Tools/code/code_haskell.ML \
$(SRC)/Tools/code/code_ml.ML \
- $(SRC)/Tools/code/code_name.ML \
$(SRC)/Tools/code/code_printer.ML \
$(SRC)/Tools/code/code_target.ML \
$(SRC)/Tools/code/code_thingol.ML \
@@ -103,10 +102,11 @@
$(SRC)/Tools/intuitionistic.ML \
$(SRC)/Tools/induct_tacs.ML \
$(SRC)/Tools/nbe.ML \
+ $(SRC)/Tools/quickcheck.ML \
$(SRC)/Tools/project_rule.ML \
$(SRC)/Tools/random_word.ML \
$(SRC)/Tools/value.ML \
- Code_Setup.thy \
+ $(SRC)/Tools/Code_Generator.thy \
HOL.thy \
Tools/hologic.ML \
Tools/recfun_codegen.ML \
@@ -206,7 +206,6 @@
MAIN_DEPENDENCIES = $(PLAIN_DEPENDENCIES) \
ATP_Linkup.thy \
Code_Eval.thy \
- Code_Message.thy \
Equiv_Relations.thy \
Groebner_Basis.thy \
Hilbert_Choice.thy \
@@ -216,29 +215,30 @@
List.thy \
Main.thy \
Map.thy \
- NatBin.thy \
+ Nat_Numeral.thy \
Presburger.thy \
Recdef.thy \
- Relation_Power.thy \
SetInterval.thy \
+ String.thy \
$(SRC)/Provers/Arith/assoc_fold.ML \
$(SRC)/Provers/Arith/cancel_numeral_factor.ML \
$(SRC)/Provers/Arith/cancel_numerals.ML \
$(SRC)/Provers/Arith/combine_numerals.ML \
$(SRC)/Provers/Arith/extract_common_term.ML \
$(SRC)/Tools/Metis/metis.ML \
- Tools/int_arith.ML \
- Tools/int_factor_simprocs.ML \
- Tools/nat_simprocs.ML \
Tools/Groebner_Basis/groebner.ML \
Tools/Groebner_Basis/misc.ML \
Tools/Groebner_Basis/normalizer_data.ML \
Tools/Groebner_Basis/normalizer.ML \
Tools/atp_manager.ML \
Tools/atp_wrapper.ML \
+ Tools/int_arith.ML \
+ Tools/list_code.ML \
Tools/meson.ML \
Tools/metis_tools.ML \
+ Tools/nat_numeral_simprocs.ML \
Tools/numeral.ML \
+ Tools/numeral_simprocs.ML \
Tools/numeral_syntax.ML \
Tools/polyhash.ML \
Tools/Qelim/cooper_data.ML \
@@ -253,6 +253,7 @@
Tools/res_hol_clause.ML \
Tools/res_reconstruct.ML \
Tools/specification_package.ML \
+ Tools/string_code.ML \
Tools/string_syntax.ML \
Tools/TFL/casesplit.ML \
Tools/TFL/dcterm.ML \
@@ -341,6 +342,7 @@
Library/Random.thy Library/Quickcheck.thy \
Library/Poly_Deriv.thy \
Library/Polynomial.thy \
+ Library/Preorder.thy \
Library/Product_plus.thy \
Library/Product_Vector.thy \
Library/Enum.thy Library/Float.thy $(SRC)/Tools/float.ML $(SRC)/HOL/Tools/float_arith.ML \
--- a/src/HOL/Library/Binomial.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Binomial.thy Mon May 11 17:20:52 2009 +0200
@@ -292,7 +292,7 @@
subsection{* Generalized binomial coefficients *}
-definition gbinomial :: "'a::{field, recpower,ring_char_0} \<Rightarrow> nat \<Rightarrow> 'a" (infixl "gchoose" 65)
+definition gbinomial :: "'a::{field, ring_char_0} \<Rightarrow> nat \<Rightarrow> 'a" (infixl "gchoose" 65)
where "a gchoose n = (if n = 0 then 1 else (setprod (\<lambda>i. a - of_nat i) {0 .. n - 1}) / of_nat (fact n))"
lemma gbinomial_0[simp]: "a gchoose 0 = 1" "0 gchoose (Suc n) = 0"
@@ -420,16 +420,16 @@
by (simp add: gbinomial_def)
lemma gbinomial_mult_fact:
- "(of_nat (fact (Suc k)) :: 'a) * ((a::'a::{field, ring_char_0,recpower}) gchoose (Suc k)) = (setprod (\<lambda>i. a - of_nat i) {0 .. k})"
+ "(of_nat (fact (Suc k)) :: 'a) * ((a::'a::{field, ring_char_0}) gchoose (Suc k)) = (setprod (\<lambda>i. a - of_nat i) {0 .. k})"
unfolding gbinomial_Suc
by (simp_all add: field_simps del: fact_Suc)
lemma gbinomial_mult_fact':
- "((a::'a::{field, ring_char_0,recpower}) gchoose (Suc k)) * (of_nat (fact (Suc k)) :: 'a) = (setprod (\<lambda>i. a - of_nat i) {0 .. k})"
+ "((a::'a::{field, ring_char_0}) gchoose (Suc k)) * (of_nat (fact (Suc k)) :: 'a) = (setprod (\<lambda>i. a - of_nat i) {0 .. k})"
using gbinomial_mult_fact[of k a]
apply (subst mult_commute) .
-lemma gbinomial_Suc_Suc: "((a::'a::{field,recpower, ring_char_0}) + 1) gchoose (Suc k) = a gchoose k + (a gchoose (Suc k))"
+lemma gbinomial_Suc_Suc: "((a::'a::{field, ring_char_0}) + 1) gchoose (Suc k) = a gchoose k + (a gchoose (Suc k))"
proof-
{assume "k = 0" then have ?thesis by simp}
moreover
--- a/src/HOL/Library/Code_Char.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Code_Char.thy Mon May 11 17:20:52 2009 +0200
@@ -14,8 +14,8 @@
(Haskell "Char")
setup {*
- fold (fn target => add_literal_char target) ["SML", "OCaml", "Haskell"]
- #> add_literal_list_string "Haskell"
+ fold String_Code.add_literal_char ["SML", "OCaml", "Haskell"]
+ #> String_Code.add_literal_list_string "Haskell"
*}
code_instance char :: eq
@@ -33,6 +33,6 @@
(Haskell infixl 4 "==")
code_const "Code_Eval.term_of \<Colon> char \<Rightarrow> term"
- (SML "HOLogic.mk'_char/ (IntInf.fromInt/ (Char.ord/ _))")
+ (Eval "HOLogic.mk'_char/ (IntInf.fromInt/ (Char.ord/ _))")
end
--- a/src/HOL/Library/Code_Index.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Code_Index.thy Mon May 11 17:20:52 2009 +0200
@@ -144,7 +144,7 @@
subsection {* Basic arithmetic *}
-instantiation index :: "{minus, ordered_semidom, Divides.div, linorder}"
+instantiation index :: "{minus, ordered_semidom, semiring_div, linorder}"
begin
definition [simp, code del]:
@@ -172,7 +172,7 @@
"n < m \<longleftrightarrow> nat_of n < nat_of m"
instance proof
-qed (auto simp add: left_distrib)
+qed (auto simp add: index left_distrib div_mult_self1)
end
--- a/src/HOL/Library/Coinductive_List.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Coinductive_List.thy Mon May 11 17:20:52 2009 +0200
@@ -786,7 +786,7 @@
lemma funpow_lmap:
fixes f :: "'a \<Rightarrow> 'a"
- shows "(lmap f ^ n) (LCons b l) = LCons ((f ^ n) b) ((lmap f ^ n) l)"
+ shows "(lmap f ^^ n) (LCons b l) = LCons ((f ^^ n) b) ((lmap f ^^ n) l)"
by (induct n) simp_all
@@ -796,35 +796,35 @@
proof
fix x
have "(h x, iterates f x) \<in>
- {((lmap f ^ n) (h u), (lmap f ^ n) (iterates f u)) | u n. True}"
+ {((lmap f ^^ n) (h u), (lmap f ^^ n) (iterates f u)) | u n. True}"
proof -
- have "(h x, iterates f x) = ((lmap f ^ 0) (h x), (lmap f ^ 0) (iterates f x))"
+ have "(h x, iterates f x) = ((lmap f ^^ 0) (h x), (lmap f ^^ 0) (iterates f x))"
by simp
then show ?thesis by blast
qed
then show "h x = iterates f x"
proof (coinduct rule: llist_equalityI)
case (Eqllist q)
- then obtain u n where "q = ((lmap f ^ n) (h u), (lmap f ^ n) (iterates f u))"
+ then obtain u n where "q = ((lmap f ^^ n) (h u), (lmap f ^^ n) (iterates f u))"
(is "_ = (?q1, ?q2)")
by auto
- also have "?q1 = LCons ((f ^ n) u) ((lmap f ^ Suc n) (h u))"
+ also have "?q1 = LCons ((f ^^ n) u) ((lmap f ^^ Suc n) (h u))"
proof -
- have "?q1 = (lmap f ^ n) (LCons u (lmap f (h u)))"
+ have "?q1 = (lmap f ^^ n) (LCons u (lmap f (h u)))"
by (subst h) rule
- also have "\<dots> = LCons ((f ^ n) u) ((lmap f ^ n) (lmap f (h u)))"
+ also have "\<dots> = LCons ((f ^^ n) u) ((lmap f ^^ n) (lmap f (h u)))"
by (rule funpow_lmap)
- also have "(lmap f ^ n) (lmap f (h u)) = (lmap f ^ Suc n) (h u)"
+ also have "(lmap f ^^ n) (lmap f (h u)) = (lmap f ^^ Suc n) (h u)"
by (simp add: funpow_swap1)
finally show ?thesis .
qed
- also have "?q2 = LCons ((f ^ n) u) ((lmap f ^ Suc n) (iterates f u))"
+ also have "?q2 = LCons ((f ^^ n) u) ((lmap f ^^ Suc n) (iterates f u))"
proof -
- have "?q2 = (lmap f ^ n) (LCons u (iterates f (f u)))"
+ have "?q2 = (lmap f ^^ n) (LCons u (iterates f (f u)))"
by (subst iterates) rule
- also have "\<dots> = LCons ((f ^ n) u) ((lmap f ^ n) (iterates f (f u)))"
+ also have "\<dots> = LCons ((f ^^ n) u) ((lmap f ^^ n) (iterates f (f u)))"
by (rule funpow_lmap)
- also have "(lmap f ^ n) (iterates f (f u)) = (lmap f ^ Suc n) (iterates f u)"
+ also have "(lmap f ^^ n) (iterates f (f u)) = (lmap f ^^ Suc n) (iterates f u)"
by (simp add: lmap_iterates funpow_swap1)
finally show ?thesis .
qed
--- a/src/HOL/Library/Commutative_Ring.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Commutative_Ring.thy Mon May 11 17:20:52 2009 +0200
@@ -27,15 +27,15 @@
text {* Interpretation functions for the shadow syntax. *}
-fun
- Ipol :: "'a::{comm_ring,recpower} list \<Rightarrow> 'a pol \<Rightarrow> 'a"
+primrec
+ Ipol :: "'a::{comm_ring_1} list \<Rightarrow> 'a pol \<Rightarrow> 'a"
where
"Ipol l (Pc c) = c"
| "Ipol l (Pinj i P) = Ipol (drop i l) P"
| "Ipol l (PX P x Q) = Ipol l P * (hd l)^x + Ipol (drop 1 l) Q"
-fun
- Ipolex :: "'a::{comm_ring,recpower} list \<Rightarrow> 'a polex \<Rightarrow> 'a"
+primrec
+ Ipolex :: "'a::{comm_ring_1} list \<Rightarrow> 'a polex \<Rightarrow> 'a"
where
"Ipolex l (Pol P) = Ipol l P"
| "Ipolex l (Add P Q) = Ipolex l P + Ipolex l Q"
@@ -54,7 +54,7 @@
PX p1 y p2 \<Rightarrow> Pinj x P)"
definition
- mkPX :: "'a::{comm_ring,recpower} pol \<Rightarrow> nat \<Rightarrow> 'a pol \<Rightarrow> 'a pol" where
+ mkPX :: "'a::{comm_ring} pol \<Rightarrow> nat \<Rightarrow> 'a pol \<Rightarrow> 'a pol" where
"mkPX P i Q = (case P of
Pc c \<Rightarrow> (if (c = 0) then (mkPinj 1 Q) else (PX P i Q)) |
Pinj j R \<Rightarrow> PX P i Q |
@@ -63,7 +63,7 @@
text {* Defining the basic ring operations on normalized polynomials *}
function
- add :: "'a::{comm_ring,recpower} pol \<Rightarrow> 'a pol \<Rightarrow> 'a pol" (infixl "\<oplus>" 65)
+ add :: "'a::{comm_ring} pol \<Rightarrow> 'a pol \<Rightarrow> 'a pol" (infixl "\<oplus>" 65)
where
"Pc a \<oplus> Pc b = Pc (a + b)"
| "Pc c \<oplus> Pinj i P = Pinj i (P \<oplus> Pc c)"
@@ -90,7 +90,7 @@
termination by (relation "measure (\<lambda>(x, y). size x + size y)") auto
function
- mul :: "'a::{comm_ring,recpower} pol \<Rightarrow> 'a pol \<Rightarrow> 'a pol" (infixl "\<otimes>" 70)
+ mul :: "'a::{comm_ring} pol \<Rightarrow> 'a pol \<Rightarrow> 'a pol" (infixl "\<otimes>" 70)
where
"Pc a \<otimes> Pc b = Pc (a * b)"
| "Pc c \<otimes> Pinj i P =
@@ -122,8 +122,8 @@
(auto simp add: mkPinj_def split: pol.split)
text {* Negation*}
-fun
- neg :: "'a::{comm_ring,recpower} pol \<Rightarrow> 'a pol"
+primrec
+ neg :: "'a::{comm_ring} pol \<Rightarrow> 'a pol"
where
"neg (Pc c) = Pc (-c)"
| "neg (Pinj i P) = Pinj i (neg P)"
@@ -131,13 +131,13 @@
text {* Substraction *}
definition
- sub :: "'a::{comm_ring,recpower} pol \<Rightarrow> 'a pol \<Rightarrow> 'a pol" (infixl "\<ominus>" 65)
+ sub :: "'a::{comm_ring} pol \<Rightarrow> 'a pol \<Rightarrow> 'a pol" (infixl "\<ominus>" 65)
where
"sub P Q = P \<oplus> neg Q"
text {* Square for Fast Exponentation *}
-fun
- sqr :: "'a::{comm_ring,recpower} pol \<Rightarrow> 'a pol"
+primrec
+ sqr :: "'a::{comm_ring_1} pol \<Rightarrow> 'a pol"
where
"sqr (Pc c) = Pc (c * c)"
| "sqr (Pinj i P) = mkPinj i (sqr P)"
@@ -146,7 +146,7 @@
text {* Fast Exponentation *}
fun
- pow :: "nat \<Rightarrow> 'a::{comm_ring,recpower} pol \<Rightarrow> 'a pol"
+ pow :: "nat \<Rightarrow> 'a::{comm_ring_1} pol \<Rightarrow> 'a pol"
where
"pow 0 P = Pc 1"
| "pow n P = (if even n then pow (n div 2) (sqr P)
@@ -161,8 +161,8 @@
text {* Normalization of polynomial expressions *}
-fun
- norm :: "'a::{comm_ring,recpower} polex \<Rightarrow> 'a pol"
+primrec
+ norm :: "'a::{comm_ring_1} polex \<Rightarrow> 'a pol"
where
"norm (Pol P) = P"
| "norm (Add P Q) = norm P \<oplus> norm Q"
--- a/src/HOL/Library/Continuity.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Continuity.thy Mon May 11 17:20:52 2009 +0200
@@ -5,7 +5,7 @@
header {* Continuity and iterations (of set transformers) *}
theory Continuity
-imports Relation_Power Main
+imports Transitive_Closure Main
begin
subsection {* Continuity for complete lattices *}
@@ -48,25 +48,25 @@
qed
lemma continuous_lfp:
- assumes "continuous F" shows "lfp F = (SUP i. (F^i) bot)"
+ assumes "continuous F" shows "lfp F = (SUP i. (F ^^ i) bot)"
proof -
note mono = continuous_mono[OF `continuous F`]
- { fix i have "(F^i) bot \<le> lfp F"
+ { fix i have "(F ^^ i) bot \<le> lfp F"
proof (induct i)
- show "(F^0) bot \<le> lfp F" by simp
+ show "(F ^^ 0) bot \<le> lfp F" by simp
next
case (Suc i)
- have "(F^(Suc i)) bot = F((F^i) bot)" by simp
+ have "(F ^^ Suc i) bot = F((F ^^ i) bot)" by simp
also have "\<dots> \<le> F(lfp F)" by(rule monoD[OF mono Suc])
also have "\<dots> = lfp F" by(simp add:lfp_unfold[OF mono, symmetric])
finally show ?case .
qed }
- hence "(SUP i. (F^i) bot) \<le> lfp F" by (blast intro!:SUP_leI)
- moreover have "lfp F \<le> (SUP i. (F^i) bot)" (is "_ \<le> ?U")
+ hence "(SUP i. (F ^^ i) bot) \<le> lfp F" by (blast intro!:SUP_leI)
+ moreover have "lfp F \<le> (SUP i. (F ^^ i) bot)" (is "_ \<le> ?U")
proof (rule lfp_lowerbound)
- have "chain(%i. (F^i) bot)"
+ have "chain(%i. (F ^^ i) bot)"
proof -
- { fix i have "(F^i) bot \<le> (F^(Suc i)) bot"
+ { fix i have "(F ^^ i) bot \<le> (F ^^ (Suc i)) bot"
proof (induct i)
case 0 show ?case by simp
next
@@ -74,7 +74,7 @@
qed }
thus ?thesis by(auto simp add:chain_def)
qed
- hence "F ?U = (SUP i. (F^(i+1)) bot)" using `continuous F` by (simp add:continuous_def)
+ hence "F ?U = (SUP i. (F ^^ (i+1)) bot)" using `continuous F` by (simp add:continuous_def)
also have "\<dots> \<le> ?U" by(fast intro:SUP_leI le_SUPI)
finally show "F ?U \<le> ?U" .
qed
@@ -193,7 +193,7 @@
definition
up_iterate :: "('a set => 'a set) => nat => 'a set" where
- "up_iterate f n = (f^n) {}"
+ "up_iterate f n = (f ^^ n) {}"
lemma up_iterate_0 [simp]: "up_iterate f 0 = {}"
by (simp add: up_iterate_def)
@@ -245,7 +245,7 @@
definition
down_iterate :: "('a set => 'a set) => nat => 'a set" where
- "down_iterate f n = (f^n) UNIV"
+ "down_iterate f n = (f ^^ n) UNIV"
lemma down_iterate_0 [simp]: "down_iterate f 0 = UNIV"
by (simp add: down_iterate_def)
--- a/src/HOL/Library/Efficient_Nat.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Efficient_Nat.thy Mon May 11 17:20:52 2009 +0200
@@ -179,10 +179,8 @@
else NONE
end;
-fun eqn_suc_preproc thy = map fst
- #> gen_eqn_suc_preproc
- @{thm Suc_if_eq} I (fst o Logic.dest_equals) thy
- #> (Option.map o map) (Code_Unit.mk_eqn thy);
+val eqn_suc_preproc = Code.simple_functrans (gen_eqn_suc_preproc
+ @{thm Suc_if_eq} I (fst o Logic.dest_equals));
fun eqn_suc_preproc' thy thms = gen_eqn_suc_preproc
@{thm Suc_if_eq'} (snd o Thm.dest_comb) (fst o HOLogic.dest_eq o HOLogic.dest_Trueprop) thy thms
--- a/src/HOL/Library/Euclidean_Space.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Euclidean_Space.thy Mon May 11 17:20:52 2009 +0200
@@ -253,13 +253,6 @@
"vector_power x 0 = 1"
| "vector_power x (Suc n) = x * vector_power x n"
-instantiation "^" :: (recpower,type) recpower
-begin
- definition vec_power_def: "op ^ \<equiv> vector_power"
- instance
- apply (intro_classes) by (simp_all add: vec_power_def)
-end
-
instance "^" :: (semiring,type) semiring
apply (intro_classes) by (vector ring_simps)+
@@ -600,7 +593,7 @@
from insert.prems have Fx: "f x \<ge> 0" and Fp: "\<forall> a \<in> F. f a \<ge> 0" by simp_all
from insert.hyps Fp setsum_nonneg[OF Fp]
have h: "setsum f F = 0 \<longleftrightarrow> (\<forall>a \<in>F. f a = 0)" by metis
- from sum_nonneg_eq_zero_iff[OF Fx setsum_nonneg[OF Fp]] insert.hyps(1,2)
+ from add_nonneg_eq_0_iff[OF Fx setsum_nonneg[OF Fp]] insert.hyps(1,2)
show ?case by (simp add: h)
qed
@@ -2762,7 +2755,7 @@
(* Geometric progression. *)
(* ------------------------------------------------------------------------- *)
-lemma sum_gp_basic: "((1::'a::{field, recpower}) - x) * setsum (\<lambda>i. x^i) {0 .. n} = (1 - x^(Suc n))"
+lemma sum_gp_basic: "((1::'a::{field}) - x) * setsum (\<lambda>i. x^i) {0 .. n} = (1 - x^(Suc n))"
(is "?lhs = ?rhs")
proof-
{assume x1: "x = 1" hence ?thesis by simp}
@@ -2780,7 +2773,7 @@
qed
lemma sum_gp_multiplied: assumes mn: "m <= n"
- shows "((1::'a::{field, recpower}) - x) * setsum (op ^ x) {m..n} = x^m - x^ Suc n"
+ shows "((1::'a::{field}) - x) * setsum (op ^ x) {m..n} = x^m - x^ Suc n"
(is "?lhs = ?rhs")
proof-
let ?S = "{0..(n - m)}"
@@ -2797,7 +2790,7 @@
by (simp add: ring_simps power_add[symmetric])
qed
-lemma sum_gp: "setsum (op ^ (x::'a::{field, recpower})) {m .. n} =
+lemma sum_gp: "setsum (op ^ (x::'a::{field})) {m .. n} =
(if n < m then 0 else if x = 1 then of_nat ((n + 1) - m)
else (x^ m - x^ (Suc n)) / (1 - x))"
proof-
@@ -2813,7 +2806,7 @@
ultimately show ?thesis by metis
qed
-lemma sum_gp_offset: "setsum (op ^ (x::'a::{field,recpower})) {m .. m+n} =
+lemma sum_gp_offset: "setsum (op ^ (x::'a::{field})) {m .. m+n} =
(if x = 1 then of_nat n + 1 else x^m * (1 - x^Suc n) / (1 - x))"
unfolding sum_gp[of x m "m + n"] power_Suc
by (simp add: ring_simps power_add)
--- a/src/HOL/Library/Eval_Witness.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Eval_Witness.thy Mon May 11 17:20:52 2009 +0200
@@ -68,7 +68,7 @@
| dest_exs _ _ = sys_error "dest_exs";
val t = dest_exs (length ws) (HOLogic.dest_Trueprop goal);
in
- if Code_ML.eval_term ("Eval_Witness_Method.eval_ref", Eval_Witness_Method.eval_ref) thy t ws
+ if Code_ML.eval NONE ("Eval_Witness_Method.eval_ref", Eval_Witness_Method.eval_ref) (K I) thy t ws
then Thm.cterm_of thy goal
else @{cprop True} (*dummy*)
end
--- a/src/HOL/Library/Float.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Float.thy Mon May 11 17:20:52 2009 +0200
@@ -15,8 +15,8 @@
datatype float = Float int int
-fun Ifloat :: "float \<Rightarrow> real" where
-"Ifloat (Float a b) = real a * pow2 b"
+primrec Ifloat :: "float \<Rightarrow> real" where
+ "Ifloat (Float a b) = real a * pow2 b"
instantiation float :: zero begin
definition zero_float where "0 = Float 0 0"
@@ -33,11 +33,11 @@
instance ..
end
-fun mantissa :: "float \<Rightarrow> int" where
-"mantissa (Float a b) = a"
+primrec mantissa :: "float \<Rightarrow> int" where
+ "mantissa (Float a b) = a"
-fun scale :: "float \<Rightarrow> int" where
-"scale (Float a b) = b"
+primrec scale :: "float \<Rightarrow> int" where
+ "scale (Float a b) = b"
lemma Ifloat_neg_exp: "e < 0 \<Longrightarrow> Ifloat (Float m e) = real m * inverse (2^nat (-e))" by auto
lemma Ifloat_nge0_exp: "\<not> 0 \<le> e \<Longrightarrow> Ifloat (Float m e) = real m * inverse (2^nat (-e))" by auto
@@ -320,12 +320,12 @@
end
instantiation float :: uminus begin
-fun uminus_float where [simp del]: "uminus_float (Float m e) = Float (-m) e"
+primrec uminus_float where [simp del]: "uminus_float (Float m e) = Float (-m) e"
instance ..
end
instantiation float :: minus begin
-fun minus_float where [simp del]: "(z::float) - w = z + (- w)"
+definition minus_float where [simp del]: "(z::float) - w = z + (- w)"
instance ..
end
@@ -334,11 +334,11 @@
instance ..
end
-fun float_pprt :: "float \<Rightarrow> float" where
-"float_pprt (Float a e) = (if 0 <= a then (Float a e) else 0)"
+primrec float_pprt :: "float \<Rightarrow> float" where
+ "float_pprt (Float a e) = (if 0 <= a then (Float a e) else 0)"
-fun float_nprt :: "float \<Rightarrow> float" where
-"float_nprt (Float a e) = (if 0 <= a then 0 else (Float a e))"
+primrec float_nprt :: "float \<Rightarrow> float" where
+ "float_nprt (Float a e) = (if 0 <= a then 0 else (Float a e))"
instantiation float :: ord begin
definition le_float_def: "z \<le> w \<equiv> Ifloat z \<le> Ifloat w"
@@ -354,7 +354,7 @@
by (cases a, simp add: uminus_float.simps)
lemma Ifloat_sub[simp]: "Ifloat (a - b) = Ifloat a - Ifloat b"
- by (cases a, cases b, simp add: minus_float.simps)
+ by (cases a, cases b, simp add: minus_float_def)
lemma Ifloat_mult[simp]: "Ifloat (a*b) = Ifloat a * Ifloat b"
by (cases a, cases b, simp add: times_float.simps pow2_add)
@@ -443,37 +443,8 @@
lemma Ifloat_min: "Ifloat (min x y) = min (Ifloat x) (Ifloat y)" unfolding min_def le_float_def by auto
lemma Ifloat_max: "Ifloat (max a b) = max (Ifloat a) (Ifloat b)" unfolding max_def le_float_def by auto
-instantiation float :: power begin
-fun power_float where [simp del]: "(Float m e) ^ n = Float (m ^ n) (e * int n)"
-instance ..
-end
-
-instance float :: recpower
-proof (intro_classes)
- fix a :: float show "a ^ 0 = 1" by (cases a, auto simp add: power_float.simps one_float_def)
-next
- fix a :: float and n :: nat show "a ^ (Suc n) = a * a ^ n"
- by (cases a, auto simp add: power_float.simps times_float.simps algebra_simps)
-qed
-
-lemma float_power: "Ifloat (x ^ n) = (Ifloat x) ^ n"
-proof (cases x)
- case (Float m e)
-
- have "pow2 e ^ n = pow2 (e * int n)"
- proof (cases "e >= 0")
- case True hence e_nat: "e = int (nat e)" by auto
- hence "pow2 e ^ n = (2 ^ nat e) ^ n" using pow2_int[of "nat e"] by auto
- thus ?thesis unfolding power_mult[symmetric] unfolding pow2_int[symmetric] int_mult e_nat[symmetric] .
- next
- case False hence e_minus: "-e = int (nat (-e))" by auto
- hence "pow2 (-e) ^ n = (2 ^ nat (-e)) ^ n" using pow2_int[of "nat (-e)"] by auto
- hence "pow2 (-e) ^ n = pow2 ((-e) * int n)" unfolding power_mult[symmetric] unfolding pow2_int[symmetric] int_mult e_minus[symmetric] zmult_zminus .
- thus ?thesis unfolding pow2_neg[of "-e"] pow2_neg[of "-e * int n"] unfolding zmult_zminus zminus_zminus nonzero_power_inverse[OF pow2_neq_zero, symmetric]
- using nonzero_inverse_eq_imp_eq[OF _ pow2_neq_zero pow2_neq_zero] by auto
- qed
- thus ?thesis by (auto simp add: Float power_mult_distrib Ifloat.simps power_float.simps)
-qed
+lemma float_power: "Ifloat (x ^ n) = Ifloat x ^ n"
+ by (induct n) simp_all
lemma zero_le_pow2[simp]: "0 \<le> pow2 s"
apply (subgoal_tac "0 < pow2 s")
@@ -1182,12 +1153,12 @@
unfolding x_eq y_eq float_divr.simps Let_def le_float_def Ifloat_0 Ifloat_mult by (auto intro!: mult_nonneg_nonpos)
qed
-fun round_down :: "nat \<Rightarrow> float \<Rightarrow> float" where
+primrec round_down :: "nat \<Rightarrow> float \<Rightarrow> float" where
"round_down prec (Float m e) = (let d = bitlen m - int prec in
if 0 < d then let P = 2^nat d ; n = m div P in Float n (e + d)
else Float m e)"
-fun round_up :: "nat \<Rightarrow> float \<Rightarrow> float" where
+primrec round_up :: "nat \<Rightarrow> float \<Rightarrow> float" where
"round_up prec (Float m e) = (let d = bitlen m - int prec in
if 0 < d then let P = 2^nat d ; n = m div P ; r = m mod P in Float (n + (if r = 0 then 0 else 1)) (e + d)
else Float m e)"
@@ -1314,8 +1285,8 @@
finally show ?thesis .
qed
-fun float_abs :: "float \<Rightarrow> float" where
-"float_abs (Float m e) = Float \<bar>m\<bar> e"
+primrec float_abs :: "float \<Rightarrow> float" where
+ "float_abs (Float m e) = Float \<bar>m\<bar> e"
instantiation float :: abs begin
definition abs_float_def: "\<bar>x\<bar> = float_abs x"
@@ -1329,8 +1300,8 @@
thus ?thesis unfolding Float abs_float_def float_abs.simps Ifloat.simps by auto
qed
-fun floor_fl :: "float \<Rightarrow> float" where
-"floor_fl (Float m e) = (if 0 \<le> e then Float m e
+primrec floor_fl :: "float \<Rightarrow> float" where
+ "floor_fl (Float m e) = (if 0 \<le> e then Float m e
else Float (m div (2 ^ (nat (-e)))) 0)"
lemma floor_fl: "Ifloat (floor_fl x) \<le> Ifloat x"
@@ -1358,8 +1329,8 @@
declare floor_fl.simps[simp del]
-fun ceiling_fl :: "float \<Rightarrow> float" where
-"ceiling_fl (Float m e) = (if 0 \<le> e then Float m e
+primrec ceiling_fl :: "float \<Rightarrow> float" where
+ "ceiling_fl (Float m e) = (if 0 \<le> e then Float m e
else Float (m div (2 ^ (nat (-e))) + 1) 0)"
lemma ceiling_fl: "Ifloat x \<le> Ifloat (ceiling_fl x)"
--- a/src/HOL/Library/Formal_Power_Series.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Formal_Power_Series.thy Mon May 11 17:20:52 2009 +0200
@@ -680,30 +680,12 @@
subsection {* Powers*}
-instantiation fps :: (semiring_1) power
-begin
-
-fun fps_pow :: "nat \<Rightarrow> 'a fps \<Rightarrow> 'a fps" where
- "fps_pow 0 f = 1"
-| "fps_pow (Suc n) f = f * fps_pow n f"
-
-definition fps_power_def: "power (f::'a fps) n = fps_pow n f"
-instance ..
-end
-
-instantiation fps :: (comm_ring_1) recpower
-begin
-instance
- apply (intro_classes)
- by (simp_all add: fps_power_def)
-end
-
lemma fps_power_zeroth_eq_one: "a$0 =1 \<Longrightarrow> a^n $ 0 = (1::'a::semiring_1)"
- by (induct n, auto simp add: fps_power_def expand_fps_eq fps_mult_nth)
+ by (induct n, auto simp add: expand_fps_eq fps_mult_nth)
lemma fps_power_first_eq: "(a:: 'a::comm_ring_1 fps)$0 =1 \<Longrightarrow> a^n $ 1 = of_nat n * a$1"
proof(induct n)
- case 0 thus ?case by (simp add: fps_power_def)
+ case 0 thus ?case by simp
next
case (Suc n)
note h = Suc.hyps[OF `a$0 = 1`]
@@ -712,16 +694,16 @@
qed
lemma startsby_one_power:"a $ 0 = (1::'a::comm_ring_1) \<Longrightarrow> a^n $ 0 = 1"
- by (induct n, auto simp add: fps_power_def fps_mult_nth)
+ by (induct n, auto simp add: fps_mult_nth)
lemma startsby_zero_power:"a $0 = (0::'a::comm_ring_1) \<Longrightarrow> n > 0 \<Longrightarrow> a^n $0 = 0"
- by (induct n, auto simp add: fps_power_def fps_mult_nth)
+ by (induct n, auto simp add: fps_mult_nth)
-lemma startsby_power:"a $0 = (v::'a::{comm_ring_1, recpower}) \<Longrightarrow> a^n $0 = v^n"
- by (induct n, auto simp add: fps_power_def fps_mult_nth power_Suc)
+lemma startsby_power:"a $0 = (v::'a::{comm_ring_1}) \<Longrightarrow> a^n $0 = v^n"
+ by (induct n, auto simp add: fps_mult_nth power_Suc)
lemma startsby_zero_power_iff[simp]:
- "a^n $0 = (0::'a::{idom, recpower}) \<longleftrightarrow> (n \<noteq> 0 \<and> a$0 = 0)"
+ "a^n $0 = (0::'a::{idom}) \<longleftrightarrow> (n \<noteq> 0 \<and> a$0 = 0)"
apply (rule iffI)
apply (induct n, auto simp add: power_Suc fps_mult_nth)
by (rule startsby_zero_power, simp_all)
@@ -764,7 +746,7 @@
apply (rule startsby_zero_power_prefix[rule_format, OF a0])
by arith
-lemma startsby_zero_power_nth_same: assumes a0: "a$0 = (0::'a::{recpower, idom})"
+lemma startsby_zero_power_nth_same: assumes a0: "a$0 = (0::'a::{idom})"
shows "a^n $ n = (a$1) ^ n"
proof(induct n)
case 0 thus ?case by (simp add: power_0)
@@ -785,7 +767,7 @@
qed
lemma fps_inverse_power:
- fixes a :: "('a::{field, recpower}) fps"
+ fixes a :: "('a::{field}) fps"
shows "inverse (a^n) = inverse a ^ n"
proof-
{assume a0: "a$0 = 0"
@@ -874,7 +856,7 @@
subsection{* The eXtractor series X*}
-lemma minus_one_power_iff: "(- (1::'a :: {recpower, comm_ring_1})) ^ n = (if even n then 1 else - 1)"
+lemma minus_one_power_iff: "(- (1::'a :: {comm_ring_1})) ^ n = (if even n then 1 else - 1)"
by (induct n, auto)
definition "X = Abs_fps (\<lambda>n. if n = 1 then 1 else 0)"
@@ -901,7 +883,7 @@
lemma X_power_iff: "X^k = Abs_fps (\<lambda>n. if n = k then (1::'a::comm_ring_1) else 0)"
proof(induct k)
- case 0 thus ?case by (simp add: X_def fps_power_def fps_eq_iff)
+ case 0 thus ?case by (simp add: X_def fps_eq_iff)
next
case (Suc k)
{fix m
@@ -931,7 +913,7 @@
by (simp add: X_power_iff)
lemma fps_inverse_X_plus1:
- "inverse (1 + X) = Abs_fps (\<lambda>n. (- (1::'a::{recpower, field})) ^ n)" (is "_ = ?r")
+ "inverse (1 + X) = Abs_fps (\<lambda>n. (- (1::'a::{field})) ^ n)" (is "_ = ?r")
proof-
have eq: "(1 + X) * ?r = 1"
unfolding minus_one_power_iff
@@ -979,7 +961,7 @@
(* {a_{n+k}}_0^infty Corresponds to (f - setsum (\<lambda>i. a_i * x^i))/x^h, for h>0*)
lemma fps_power_mult_eq_shift:
- "X^Suc k * Abs_fps (\<lambda>n. a (n + Suc k)) = Abs_fps a - setsum (\<lambda>i. fps_const (a i :: 'a:: field) * X^i) {0 .. k}" (is "?lhs = ?rhs")
+ "X^Suc k * Abs_fps (\<lambda>n. a (n + Suc k)) = Abs_fps a - setsum (\<lambda>i. fps_const (a i :: 'a:: comm_ring_1) * X^i) {0 .. k}" (is "?lhs = ?rhs")
proof-
{fix n:: nat
have "?lhs $ n = (if n < Suc k then 0 else a n)"
@@ -990,7 +972,7 @@
next
case (Suc k)
note th = Suc.hyps[symmetric]
- have "(Abs_fps a - setsum (\<lambda>i. fps_const (a i :: 'a:: field) * X^i) {0 .. Suc k})$n = (Abs_fps a - setsum (\<lambda>i. fps_const (a i :: 'a:: field) * X^i) {0 .. k} - fps_const (a (Suc k)) * X^ Suc k) $ n" by (simp add: ring_simps)
+ have "(Abs_fps a - setsum (\<lambda>i. fps_const (a i :: 'a) * X^i) {0 .. Suc k})$n = (Abs_fps a - setsum (\<lambda>i. fps_const (a i :: 'a) * X^i) {0 .. k} - fps_const (a (Suc k)) * X^ Suc k) $ n" by (simp add: ring_simps)
also have "\<dots> = (if n < Suc k then 0 else a n) - (fps_const (a (Suc k)) * X^ Suc k)$n"
using th
unfolding fps_sub_nth by simp
@@ -1022,13 +1004,16 @@
lemma XD_linear[simp]: "XD (fps_const c * a + fps_const d * b) = fps_const c * XD a + fps_const d * XD (b :: ('a::comm_ring_1) fps)"
by simp
-lemma XDN_linear: "(XD^n) (fps_const c * a + fps_const d * b) = fps_const c * (XD^n) a + fps_const d * (XD^n) (b :: ('a::comm_ring_1) fps)"
+lemma XDN_linear:
+ "(XD ^^ n) (fps_const c * a + fps_const d * b) = fps_const c * (XD ^^ n) a + fps_const d * (XD ^^ n) (b :: ('a::comm_ring_1) fps)"
by (induct n, simp_all)
lemma fps_mult_X_deriv_shift: "X* fps_deriv a = Abs_fps (\<lambda>n. of_nat n* a$n)" by (simp add: fps_eq_iff)
-lemma fps_mult_XD_shift: "(XD ^k) (a:: ('a::{comm_ring_1, recpower, ring_char_0}) fps) = Abs_fps (\<lambda>n. (of_nat n ^ k) * a$n)"
-by (induct k arbitrary: a) (simp_all add: power_Suc XD_def fps_eq_iff ring_simps del: One_nat_def)
+
+lemma fps_mult_XD_shift:
+ "(XD ^^ k) (a:: ('a::{comm_ring_1}) fps) = Abs_fps (\<lambda>n. (of_nat n ^ k) * a$n)"
+ by (induct k arbitrary: a) (simp_all add: power_Suc XD_def fps_eq_iff ring_simps del: One_nat_def)
subsubsection{* Rule 3 is trivial and is given by @{text fps_times_def}*}
subsubsection{* Rule 5 --- summation and "division" by (1 - X)*}
@@ -1309,7 +1294,7 @@
by (cases m, simp_all add: fps_power_nth_Suc del: power_Suc)
lemma fps_nth_power_0:
- fixes m :: nat and a :: "('a::{comm_ring_1, recpower}) fps"
+ fixes m :: nat and a :: "('a::{comm_ring_1}) fps"
shows "(a ^m)$0 = (a$0) ^ m"
proof-
{assume "m=0" hence ?thesis by simp}
@@ -1325,7 +1310,7 @@
qed
lemma fps_compose_inj_right:
- assumes a0: "a$0 = (0::'a::{recpower,idom})"
+ assumes a0: "a$0 = (0::'a::{idom})"
and a1: "a$1 \<noteq> 0"
shows "(b oo a = c oo a) \<longleftrightarrow> b = c" (is "?lhs \<longleftrightarrow>?rhs")
proof-
@@ -1366,7 +1351,7 @@
subsection {* Radicals *}
declare setprod_cong[fundef_cong]
-function radical :: "(nat \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> ('a::{field, recpower}) fps \<Rightarrow> nat \<Rightarrow> 'a" where
+function radical :: "(nat \<Rightarrow> 'a \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> ('a::{field}) fps \<Rightarrow> nat \<Rightarrow> 'a" where
"radical r 0 a 0 = 1"
| "radical r 0 a (Suc n) = 0"
| "radical r (Suc k) a 0 = r (Suc k) (a$0)"
@@ -1454,7 +1439,68 @@
qed
lemma power_radical:
- fixes a:: "'a ::{field, ring_char_0, recpower} fps"
+ fixes a:: "'a ::{field, ring_char_0} fps"
+ assumes a0: "a$0 \<noteq> 0"
+ shows "(r (Suc k) (a$0)) ^ Suc k = a$0 \<longleftrightarrow> (fps_radical r (Suc k) a) ^ (Suc k) = a"
+proof-
+ let ?r = "fps_radical r (Suc k) a"
+ {assume r0: "(r (Suc k) (a$0)) ^ Suc k = a$0"
+ from a0 r0 have r00: "r (Suc k) (a$0) \<noteq> 0" by auto
+ {fix z have "?r ^ Suc k $ z = a$z"
+ proof(induct z rule: nat_less_induct)
+ fix n assume H: "\<forall>m<n. ?r ^ Suc k $ m = a$m"
+ {assume "n = 0" hence "?r ^ Suc k $ n = a $n"
+ using fps_radical_power_nth[of r "Suc k" a, OF r0] by simp}
+ moreover
+ {fix n1 assume n1: "n = Suc n1"
+ have fK: "finite {0..k}" by simp
+ have nz: "n \<noteq> 0" using n1 by arith
+ let ?Pnk = "natpermute n (k + 1)"
+ let ?Pnkn = "{xs \<in> ?Pnk. n \<in> set xs}"
+ let ?Pnknn = "{xs \<in> ?Pnk. n \<notin> set xs}"
+ have eq: "?Pnkn \<union> ?Pnknn = ?Pnk" by blast
+ have d: "?Pnkn \<inter> ?Pnknn = {}" by blast
+ have f: "finite ?Pnkn" "finite ?Pnknn"
+ using finite_Un[of ?Pnkn ?Pnknn, unfolded eq]
+ by (metis natpermute_finite)+
+ let ?f = "\<lambda>v. \<Prod>j\<in>{0..k}. ?r $ v ! j"
+ have "setsum ?f ?Pnkn = setsum (\<lambda>v. ?r $ n * r (Suc k) (a $ 0) ^ k) ?Pnkn"
+ proof(rule setsum_cong2)
+ fix v assume v: "v \<in> {xs \<in> natpermute n (k + 1). n \<in> set xs}"
+ let ?ths = "(\<Prod>j\<in>{0..k}. fps_radical r (Suc k) a $ v ! j) = fps_radical r (Suc k) a $ n * r (Suc k) (a $ 0) ^ k"
+ from v obtain i where i: "i \<in> {0..k}" "v = replicate (k+1) 0 [i:= n]"
+ unfolding natpermute_contain_maximal by auto
+ have "(\<Prod>j\<in>{0..k}. fps_radical r (Suc k) a $ v ! j) = (\<Prod>j\<in>{0..k}. if j = i then fps_radical r (Suc k) a $ n else r (Suc k) (a$0))"
+ apply (rule setprod_cong, simp)
+ using i r0 by (simp del: replicate.simps)
+ also have "\<dots> = (fps_radical r (Suc k) a $ n) * r (Suc k) (a$0) ^ k"
+ unfolding setprod_gen_delta[OF fK] using i r0 by simp
+ finally show ?ths .
+ qed
+ then have "setsum ?f ?Pnkn = of_nat (k+1) * ?r $ n * r (Suc k) (a $ 0) ^ k"
+ by (simp add: natpermute_max_card[OF nz, simplified])
+ also have "\<dots> = a$n - setsum ?f ?Pnknn"
+ unfolding n1 using r00 a0 by (simp add: field_simps fps_radical_def del: of_nat_Suc )
+ finally have fn: "setsum ?f ?Pnkn = a$n - setsum ?f ?Pnknn" .
+ have "(?r ^ Suc k)$n = setsum ?f ?Pnkn + setsum ?f ?Pnknn"
+ unfolding fps_power_nth_Suc setsum_Un_disjoint[OF f d, unfolded eq] ..
+ also have "\<dots> = a$n" unfolding fn by simp
+ finally have "?r ^ Suc k $ n = a $n" .}
+ ultimately show "?r ^ Suc k $ n = a $n" by (cases n, auto)
+ qed }
+ then have ?thesis using r0 by (simp add: fps_eq_iff)}
+moreover
+{ assume h: "(fps_radical r (Suc k) a) ^ (Suc k) = a"
+ hence "((fps_radical r (Suc k) a) ^ (Suc k))$0 = a$0" by simp
+ then have "(r (Suc k) (a$0)) ^ Suc k = a$0"
+ unfolding fps_power_nth_Suc
+ by (simp add: setprod_constant del: replicate.simps)}
+ultimately show ?thesis by blast
+qed
+
+(*
+lemma power_radical:
+ fixes a:: "'a ::{field, ring_char_0} fps"
assumes r0: "(r (Suc k) (a$0)) ^ Suc k = a$0" and a0: "a$0 \<noteq> 0"
shows "(fps_radical r (Suc k) a) ^ (Suc k) = a"
proof-
@@ -1505,6 +1551,7 @@
then show ?thesis by (simp add: fps_eq_iff)
qed
+*)
lemma eq_divide_imp': assumes c0: "(c::'a::field) ~= 0" and eq: "a * c = b"
shows "a = b / c"
proof-
@@ -1515,16 +1562,15 @@
lemma radical_unique:
assumes r0: "(r (Suc k) (b$0)) ^ Suc k = b$0"
- and a0: "r (Suc k) (b$0 ::'a::{field, ring_char_0, recpower}) = a$0" and b0: "b$0 \<noteq> 0"
+ and a0: "r (Suc k) (b$0 ::'a::{field, ring_char_0}) = a$0" and b0: "b$0 \<noteq> 0"
shows "a^(Suc k) = b \<longleftrightarrow> a = fps_radical r (Suc k) b"
proof-
let ?r = "fps_radical r (Suc k) b"
have r00: "r (Suc k) (b$0) \<noteq> 0" using b0 r0 by auto
{assume H: "a = ?r"
- from H have "a^Suc k = b" using power_radical[of r k, OF r0 b0] by simp}
+ from H have "a^Suc k = b" using power_radical[OF b0, of r k, unfolded r0] by simp}
moreover
{assume H: "a^Suc k = b"
- (* Generally a$0 would need to be the k+1 st root of b$0 *)
have ceq: "card {0..k} = Suc k" by simp
have fk: "finite {0..k}" by simp
from a0 have a0r0: "a$0 = ?r$0" by simp
@@ -1610,7 +1656,7 @@
lemma radical_power:
assumes r0: "r (Suc k) ((a$0) ^ Suc k) = a$0"
- and a0: "(a$0 ::'a::{field, ring_char_0, recpower}) \<noteq> 0"
+ and a0: "(a$0 ::'a::{field, ring_char_0}) \<noteq> 0"
shows "(fps_radical r (Suc k) (a ^ Suc k)) = a"
proof-
let ?ak = "a^ Suc k"
@@ -1622,7 +1668,7 @@
qed
lemma fps_deriv_radical:
- fixes a:: "'a ::{field, ring_char_0, recpower} fps"
+ fixes a:: "'a ::{field, ring_char_0} fps"
assumes r0: "(r (Suc k) (a$0)) ^ Suc k = a$0" and a0: "a$0 \<noteq> 0"
shows "fps_deriv (fps_radical r (Suc k) a) = fps_deriv a / (fps_const (of_nat (Suc k)) * (fps_radical r (Suc k) a) ^ k)"
proof-
@@ -1632,7 +1678,7 @@
from r0' have w0: "?w $ 0 \<noteq> 0" by (simp del: of_nat_Suc)
note th0 = inverse_mult_eq_1[OF w0]
let ?iw = "inverse ?w"
- from power_radical[of r, OF r0 a0]
+ from iffD1[OF power_radical[of a r], OF a0 r0]
have "fps_deriv (?r ^ Suc k) = fps_deriv a" by simp
hence "fps_deriv ?r * ?w = fps_deriv a"
by (simp add: fps_deriv_power mult_ac del: power_Suc)
@@ -1643,11 +1689,45 @@
qed
lemma radical_mult_distrib:
- fixes a:: "'a ::{field, ring_char_0, recpower} fps"
+ fixes a:: "'a ::{field, ring_char_0} fps"
assumes
- ra0: "r (k) (a $ 0) ^ k = a $ 0"
- and rb0: "r (k) (b $ 0) ^ k = b $ 0"
- and r0': "r (k) ((a * b) $ 0) = r (k) (a $ 0) * r (k) (b $ 0)"
+ k: "k > 0"
+ and ra0: "r k (a $ 0) ^ k = a $ 0"
+ and rb0: "r k (b $ 0) ^ k = b $ 0"
+ and a0: "a$0 \<noteq> 0"
+ and b0: "b$0 \<noteq> 0"
+ shows "r k ((a * b) $ 0) = r k (a $ 0) * r k (b $ 0) \<longleftrightarrow> fps_radical r (k) (a*b) = fps_radical r (k) a * fps_radical r (k) (b)"
+proof-
+ {assume r0': "r k ((a * b) $ 0) = r k (a $ 0) * r k (b $ 0)"
+ from r0' have r0: "(r (k) ((a*b)$0)) ^ k = (a*b)$0"
+ by (simp add: fps_mult_nth ra0 rb0 power_mult_distrib)
+ {assume "k=0" hence ?thesis using r0' by simp}
+ moreover
+ {fix h assume k: "k = Suc h"
+ let ?ra = "fps_radical r (Suc h) a"
+ let ?rb = "fps_radical r (Suc h) b"
+ have th0: "r (Suc h) ((a * b) $ 0) = (fps_radical r (Suc h) a * fps_radical r (Suc h) b) $ 0"
+ using r0' k by (simp add: fps_mult_nth)
+ have ab0: "(a*b) $ 0 \<noteq> 0" using a0 b0 by (simp add: fps_mult_nth)
+ from radical_unique[of r h "a*b" "fps_radical r (Suc h) a * fps_radical r (Suc h) b", OF r0[unfolded k] th0 ab0, symmetric]
+ iffD1[OF power_radical[of _ r], OF a0 ra0[unfolded k]] iffD1[OF power_radical[of _ r], OF b0 rb0[unfolded k]] k r0'
+ have ?thesis by (auto simp add: power_mult_distrib simp del: power_Suc)}
+ultimately have ?thesis by (cases k, auto)}
+moreover
+{assume h: "fps_radical r k (a*b) = fps_radical r k a * fps_radical r k b"
+ hence "(fps_radical r k (a*b))$0 = (fps_radical r k a * fps_radical r k b)$0" by simp
+ then have "r k ((a * b) $ 0) = r k (a $ 0) * r k (b $ 0)"
+ using k by (simp add: fps_mult_nth)}
+ultimately show ?thesis by blast
+qed
+
+(*
+lemma radical_mult_distrib:
+ fixes a:: "'a ::{field, ring_char_0} fps"
+ assumes
+ ra0: "r k (a $ 0) ^ k = a $ 0"
+ and rb0: "r k (b $ 0) ^ k = b $ 0"
+ and r0': "r k ((a * b) $ 0) = r k (a $ 0) * r k (b $ 0)"
and a0: "a$0 \<noteq> 0"
and b0: "b$0 \<noteq> 0"
shows "fps_radical r (k) (a*b) = fps_radical r (k) a * fps_radical r (k) (b)"
@@ -1667,88 +1747,60 @@
have ?thesis by (auto simp add: power_mult_distrib simp del: power_Suc)}
ultimately show ?thesis by (cases k, auto)
qed
+*)
-lemma radical_inverse:
- fixes a:: "'a ::{field, ring_char_0, recpower} fps"
- assumes
- ra0: "r (k) (a $ 0) ^ k = a $ 0"
- and ria0: "r (k) (inverse (a $ 0)) = inverse (r (k) (a $ 0))"
- and r1: "(r (k) 1) = 1"
- and a0: "a$0 \<noteq> 0"
- shows "fps_radical r (k) (inverse a) = inverse (fps_radical r (k) a)"
-proof-
- {assume "k=0" then have ?thesis by simp}
- moreover
- {fix h assume k[simp]: "k = Suc h"
- let ?ra = "fps_radical r (Suc h) a"
- let ?ria = "fps_radical r (Suc h) (inverse a)"
- from ra0 a0 have th00: "r (Suc h) (a$0) \<noteq> 0" by auto
- have ria0': "r (Suc h) (inverse a $ 0) ^ Suc h = inverse a$0"
- using ria0 ra0 a0
- by (simp add: fps_inverse_def nonzero_power_inverse[OF th00, symmetric]
- del: power_Suc)
- from inverse_mult_eq_1[OF a0] have th0: "a * inverse a = 1"
- by (simp add: mult_commute)
- from radical_unique[where a=1 and b=1 and r=r and k=h, simplified, OF r1[unfolded k]]
- have th01: "fps_radical r (Suc h) 1 = 1" .
- have th1: "r (Suc h) ((a * inverse a) $ 0) ^ Suc h = (a * inverse a) $ 0"
- "r (Suc h) ((a * inverse a) $ 0) =
-r (Suc h) (a $ 0) * r (Suc h) (inverse a $ 0)"
- using r1 unfolding th0 apply (simp_all add: ria0[symmetric])
- apply (simp add: fps_inverse_def a0)
- unfolding ria0[unfolded k]
- using th00 by simp
- from nonzero_imp_inverse_nonzero[OF a0] a0
- have th2: "inverse a $ 0 \<noteq> 0" by (simp add: fps_inverse_def)
- from radical_mult_distrib[of r "Suc h" a "inverse a", OF ra0[unfolded k] ria0' th1(2) a0 th2]
- have th3: "?ra * ?ria = 1" unfolding th0 th01 by simp
- from th00 have ra0: "?ra $ 0 \<noteq> 0" by simp
- from fps_inverse_unique[OF ra0 th3] have ?thesis by simp}
-ultimately show ?thesis by (cases k, auto)
-qed
-
-lemma fps_divide_inverse: "(a::('a::field) fps) / b = a * inverse b"
+lemma fps_divide_1[simp]: "(a:: ('a::field) fps) / 1 = a"
by (simp add: fps_divide_def)
lemma radical_divide:
- fixes a:: "'a ::{field, ring_char_0, recpower} fps"
+ fixes a:: "'a ::{field, ring_char_0} fps"
assumes
- ra0: "r k (a $ 0) ^ k = a $ 0"
- and rb0: "r k (b $ 0) ^ k = b $ 0"
- and r1: "r k 1 = 1"
- and rb0': "r k (inverse (b $ 0)) = inverse (r k (b $ 0))"
- and raib': "r k (a$0 / (b$0)) = r k (a$0) / r k (b$0)"
+ kp: "k>0"
+ and ra0: "(r k (a $ 0)) ^ k = a $ 0"
+ and rb0: "(r k (b $ 0)) ^ k = b $ 0"
and a0: "a$0 \<noteq> 0"
and b0: "b$0 \<noteq> 0"
- shows "fps_radical r k (a/b) = fps_radical r k a / fps_radical r k b"
+ shows "r k ((a $ 0) / (b$0)) = r k (a$0) / r k (b $ 0) \<longleftrightarrow> fps_radical r k (a/b) = fps_radical r k a / fps_radical r k b" (is "?lhs = ?rhs")
proof-
- from raib'
- have raib: "r k (a$0 / (b$0)) = r k (a$0) * r k (inverse (b$0))"
- by (simp add: divide_inverse rb0'[symmetric])
-
- {assume "k=0" hence ?thesis by (simp add: fps_divide_def)}
- moreover
- {assume k0: "k\<noteq> 0"
- from b0 k0 rb0 have rbn0: "r k (b $0) \<noteq> 0"
- by (auto simp add: power_0_left)
+ let ?r = "fps_radical r k"
+ from kp obtain h where k: "k = Suc h" by (cases k, auto)
+ have ra0': "r k (a$0) \<noteq> 0" using a0 ra0 k by auto
+ have rb0': "r k (b$0) \<noteq> 0" using b0 rb0 k by auto
- from rb0 rb0' have rib0: "(r k (inverse (b $ 0)))^k = inverse (b$0)"
- by (simp add: nonzero_power_inverse[OF rbn0, symmetric])
- from rib0 have th0: "r k (inverse b $ 0) ^ k = inverse b $ 0"
- by (simp add:fps_inverse_def b0)
- from raib
- have th1: "r k ((a * inverse b) $ 0) = r k (a $ 0) * r k (inverse b $ 0)"
- by (simp add: divide_inverse fps_inverse_def b0 fps_mult_nth)
- from nonzero_imp_inverse_nonzero[OF b0] b0 have th2: "inverse b $ 0 \<noteq> 0"
- by (simp add: fps_inverse_def)
- from radical_mult_distrib[of r k a "inverse b", OF ra0 th0 th1 a0 th2]
- have th: "fps_radical r k (a/b) = fps_radical r k a * fps_radical r k (inverse b)"
- by (simp add: fps_divide_def)
- with radical_inverse[of r k b, OF rb0 rb0' r1 b0]
- have ?thesis by (simp add: fps_divide_def)}
-ultimately show ?thesis by blast
+ {assume ?rhs
+ then have "?r (a/b) $ 0 = (?r a / ?r b)$0" by simp
+ then have ?lhs using k a0 b0 rb0'
+ by (simp add: fps_divide_def fps_mult_nth fps_inverse_def divide_inverse) }
+ moreover
+ {assume h: ?lhs
+ from a0 b0 have ab0[simp]: "(a/b)$0 = a$0 / b$0"
+ by (simp add: fps_divide_def fps_mult_nth divide_inverse fps_inverse_def)
+ have th0: "r k ((a/b)$0) ^ k = (a/b)$0"
+ by (simp add: h nonzero_power_divide[OF rb0'] ra0 rb0 del: k)
+ from a0 b0 ra0' rb0' kp h
+ have th1: "r k ((a / b) $ 0) = (fps_radical r k a / fps_radical r k b) $ 0"
+ by (simp add: fps_divide_def fps_mult_nth fps_inverse_def divide_inverse del: k)
+ from a0 b0 ra0' rb0' kp have ab0': "(a / b) $ 0 \<noteq> 0"
+ by (simp add: fps_divide_def fps_mult_nth fps_inverse_def nonzero_imp_inverse_nonzero)
+ note tha[simp] = iffD1[OF power_radical[where r=r and k=h], OF a0 ra0[unfolded k], unfolded k[symmetric]]
+ note thb[simp] = iffD1[OF power_radical[where r=r and k=h], OF b0 rb0[unfolded k], unfolded k[symmetric]]
+ have th2: "(?r a / ?r b)^k = a/b"
+ by (simp add: fps_divide_def power_mult_distrib fps_inverse_power[symmetric])
+ from iffD1[OF radical_unique[where r=r and a="?r a / ?r b" and b="a/b" and k=h], symmetric, unfolded k[symmetric], OF th0 th1 ab0' th2] have ?rhs .}
+ ultimately show ?thesis by blast
qed
+lemma radical_inverse:
+ fixes a:: "'a ::{field, ring_char_0} fps"
+ assumes
+ k: "k>0"
+ and ra0: "r k (a $ 0) ^ k = a $ 0"
+ and r1: "(r k 1)^k = 1"
+ and a0: "a$0 \<noteq> 0"
+ shows "r k (inverse (a $ 0)) = r k 1 / (r k (a $ 0)) \<longleftrightarrow> fps_radical r k (inverse a) = fps_radical r k 1 / fps_radical r k a"
+ using radical_divide[where k=k and r=r and a=1 and b=a, OF k ] ra0 r1 a0
+ by (simp add: divide_inverse fps_divide_def)
+
subsection{* Derivative of composition *}
lemma fps_compose_deriv:
@@ -1831,7 +1883,7 @@
subsection{* Compositional inverses *}
-fun compinv :: "'a fps \<Rightarrow> nat \<Rightarrow> 'a::{recpower,field}" where
+fun compinv :: "'a fps \<Rightarrow> nat \<Rightarrow> 'a::{field}" where
"compinv a 0 = X$0"
| "compinv a (Suc n) = (X$ Suc n - setsum (\<lambda>i. (compinv a i) * (a^i)$Suc n) {0 .. n}) / (a$1) ^ Suc n"
@@ -1862,7 +1914,7 @@
qed
-fun gcompinv :: "'a fps \<Rightarrow> 'a fps \<Rightarrow> nat \<Rightarrow> 'a::{recpower,field}" where
+fun gcompinv :: "'a fps \<Rightarrow> 'a fps \<Rightarrow> nat \<Rightarrow> 'a::{field}" where
"gcompinv b a 0 = b$0"
| "gcompinv b a (Suc n) = (b$ Suc n - setsum (\<lambda>i. (gcompinv b a i) * (a^i)$Suc n) {0 .. n}) / (a$1) ^ Suc n"
@@ -1901,19 +1953,16 @@
done
lemma fps_compose_1[simp]: "1 oo a = 1"
- by (simp add: fps_eq_iff fps_compose_nth fps_power_def mult_delta_left setsum_delta)
+ by (simp add: fps_eq_iff fps_compose_nth mult_delta_left setsum_delta)
lemma fps_compose_0[simp]: "0 oo a = 0"
by (simp add: fps_eq_iff fps_compose_nth)
-lemma fps_pow_0: "fps_pow n 0 = (if n = 0 then 1 else 0)"
- by (induct n, simp_all)
-
lemma fps_compose_0_right[simp]: "a oo 0 = fps_const (a$0)"
- by (auto simp add: fps_eq_iff fps_compose_nth fps_power_def fps_pow_0 setsum_0')
+ by (auto simp add: fps_eq_iff fps_compose_nth power_0_left setsum_0')
lemma fps_compose_add_distrib: "(a + b) oo c = (a oo c) + (b oo c)"
- by (simp add: fps_eq_iff fps_compose_nth ring_simps setsum_addf)
+ by (simp add: fps_eq_iff fps_compose_nth ring_simps setsum_addf)
lemma fps_compose_setsum_distrib: "(setsum f S) oo a = setsum (\<lambda>i. f i oo a) S"
proof-
@@ -2118,7 +2167,7 @@
qed
lemma fps_inv_deriv:
- assumes a0:"a$0 = (0::'a::{recpower,field})" and a1: "a$1 \<noteq> 0"
+ assumes a0:"a$0 = (0::'a::{field})" and a1: "a$1 \<noteq> 0"
shows "fps_deriv (fps_inv a) = inverse (fps_deriv a oo fps_inv a)"
proof-
let ?ia = "fps_inv a"
@@ -2138,7 +2187,7 @@
subsubsection{* Exponential series *}
definition "E x = Abs_fps (\<lambda>n. x^n / of_nat (fact n))"
-lemma E_deriv[simp]: "fps_deriv (E a) = fps_const (a::'a::{field, recpower, ring_char_0}) * E a" (is "?l = ?r")
+lemma E_deriv[simp]: "fps_deriv (E a) = fps_const (a::'a::{field, ring_char_0}) * E a" (is "?l = ?r")
proof-
{fix n
have "?l$n = ?r $ n"
@@ -2148,7 +2197,7 @@
qed
lemma E_unique_ODE:
- "fps_deriv a = fps_const c * a \<longleftrightarrow> a = fps_const (a$0) * E (c :: 'a::{field, ring_char_0, recpower})"
+ "fps_deriv a = fps_const c * a \<longleftrightarrow> a = fps_const (a$0) * E (c :: 'a::{field, ring_char_0})"
(is "?lhs \<longleftrightarrow> ?rhs")
proof-
{assume d: ?lhs
@@ -2175,7 +2224,7 @@
ultimately show ?thesis by blast
qed
-lemma E_add_mult: "E (a + b) = E (a::'a::{ring_char_0, field, recpower}) * E b" (is "?l = ?r")
+lemma E_add_mult: "E (a + b) = E (a::'a::{ring_char_0, field}) * E b" (is "?l = ?r")
proof-
have "fps_deriv (?r) = fps_const (a+b) * ?r"
by (simp add: fps_const_add[symmetric] ring_simps del: fps_const_add)
@@ -2187,10 +2236,10 @@
lemma E_nth[simp]: "E a $ n = a^n / of_nat (fact n)"
by (simp add: E_def)
-lemma E0[simp]: "E (0::'a::{field, recpower}) = 1"
+lemma E0[simp]: "E (0::'a::{field}) = 1"
by (simp add: fps_eq_iff power_0_left)
-lemma E_neg: "E (- a) = inverse (E (a::'a::{ring_char_0, field, recpower}))"
+lemma E_neg: "E (- a) = inverse (E (a::'a::{ring_char_0, field}))"
proof-
from E_add_mult[of a "- a"] have th0: "E a * E (- a) = 1"
by (simp )
@@ -2198,7 +2247,7 @@
from fps_inverse_unique[OF th1 th0] show ?thesis by simp
qed
-lemma E_nth_deriv[simp]: "fps_nth_deriv n (E (a::'a::{field, recpower, ring_char_0})) = (fps_const a)^n * (E a)"
+lemma E_nth_deriv[simp]: "fps_nth_deriv n (E (a::'a::{field, ring_char_0})) = (fps_const a)^n * (E a)"
by (induct n, auto simp add: power_Suc)
lemma fps_compose_uminus: "- (a::'a::ring_1 fps) oo c = - (a oo c)"
@@ -2211,7 +2260,7 @@
lemma X_fps_compose:"X oo a = Abs_fps (\<lambda>n. if n = 0 then (0::'a::comm_ring_1) else a$n)"
by (simp add: fps_eq_iff fps_compose_nth mult_delta_left setsum_delta power_Suc)
-lemma X_compose_E[simp]: "X oo E (a::'a::{field, recpower}) = E a - 1"
+lemma X_compose_E[simp]: "X oo E (a::'a::{field}) = E a - 1"
by (simp add: fps_eq_iff X_fps_compose)
lemma LE_compose:
@@ -2233,7 +2282,7 @@
lemma inverse_one_plus_X:
- "inverse (1 + X) = Abs_fps (\<lambda>n. (- 1 ::'a::{field, recpower})^n)"
+ "inverse (1 + X) = Abs_fps (\<lambda>n. (- 1 ::'a::{field})^n)"
(is "inverse ?l = ?r")
proof-
have th: "?l * ?r = 1"
@@ -2244,11 +2293,11 @@
from fps_inverse_unique[OF th' th] show ?thesis .
qed
-lemma E_power_mult: "(E (c::'a::{field,recpower,ring_char_0}))^n = E (of_nat n * c)"
+lemma E_power_mult: "(E (c::'a::{field,ring_char_0}))^n = E (of_nat n * c)"
by (induct n, auto simp add: ring_simps E_add_mult power_Suc)
subsubsection{* Logarithmic series *}
-definition "(L::'a::{field, ring_char_0,recpower} fps)
+definition "(L::'a::{field, ring_char_0} fps)
= Abs_fps (\<lambda>n. (- 1) ^ Suc n / of_nat n)"
lemma fps_deriv_L: "fps_deriv L = inverse (1 + X)"
@@ -2259,7 +2308,7 @@
by (simp add: L_def)
lemma L_E_inv:
- assumes a: "a\<noteq> (0::'a::{field,division_by_zero,ring_char_0,recpower})"
+ assumes a: "a\<noteq> (0::'a::{field,division_by_zero,ring_char_0})"
shows "L = fps_const a * fps_inv (E a - 1)" (is "?l = ?r")
proof-
let ?b = "E a - 1"
@@ -2283,10 +2332,10 @@
subsubsection{* Formal trigonometric functions *}
-definition "fps_sin (c::'a::{field, recpower, ring_char_0}) =
+definition "fps_sin (c::'a::{field, ring_char_0}) =
Abs_fps (\<lambda>n. if even n then 0 else (- 1) ^((n - 1) div 2) * c^n /(of_nat (fact n)))"
-definition "fps_cos (c::'a::{field, recpower, ring_char_0}) = Abs_fps (\<lambda>n. if even n then (- 1) ^ (n div 2) * c^n / (of_nat (fact n)) else 0)"
+definition "fps_cos (c::'a::{field, ring_char_0}) = Abs_fps (\<lambda>n. if even n then (- 1) ^ (n div 2) * c^n / (of_nat (fact n)) else 0)"
lemma fps_sin_deriv:
"fps_deriv (fps_sin c) = fps_const c * fps_cos c"
@@ -2341,11 +2390,11 @@
proof-
have "fps_deriv ?lhs = 0"
apply (simp add: fps_deriv_power fps_sin_deriv fps_cos_deriv power_Suc)
- by (simp add: fps_power_def ring_simps fps_const_neg[symmetric] del: fps_const_neg)
+ by (simp add: ring_simps fps_const_neg[symmetric] del: fps_const_neg)
then have "?lhs = fps_const (?lhs $ 0)"
unfolding fps_deriv_eq_0_iff .
also have "\<dots> = 1"
- by (auto simp add: fps_eq_iff fps_power_def numeral_2_eq_2 fps_mult_nth fps_cos_def fps_sin_def)
+ by (auto simp add: fps_eq_iff numeral_2_eq_2 fps_mult_nth fps_cos_def fps_sin_def)
finally show ?thesis .
qed
--- a/src/HOL/Library/FrechetDeriv.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/FrechetDeriv.thy Mon May 11 17:20:52 2009 +0200
@@ -382,7 +382,7 @@
subsection {* Powers *}
lemma FDERIV_power_Suc:
- fixes x :: "'a::{real_normed_algebra,recpower,comm_ring_1}"
+ fixes x :: "'a::{real_normed_algebra,comm_ring_1}"
shows "FDERIV (\<lambda>x. x ^ Suc n) x :> (\<lambda>h. (1 + of_nat n) * x ^ n * h)"
apply (induct n)
apply (simp add: power_Suc FDERIV_ident)
@@ -392,7 +392,7 @@
done
lemma FDERIV_power:
- fixes x :: "'a::{real_normed_algebra,recpower,comm_ring_1}"
+ fixes x :: "'a::{real_normed_algebra,comm_ring_1}"
shows "FDERIV (\<lambda>x. x ^ n) x :> (\<lambda>h. of_nat n * x ^ (n - 1) * h)"
apply (cases n)
apply (simp add: FDERIV_const)
--- a/src/HOL/Library/Fundamental_Theorem_Algebra.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Fundamental_Theorem_Algebra.thy Mon May 11 17:20:52 2009 +0200
@@ -560,14 +560,14 @@
done
lemma poly_replicate_append:
- "poly (monom 1 n * p) (x::'a::{recpower, comm_ring_1}) = x^n * poly p x"
+ "poly (monom 1 n * p) (x::'a::{comm_ring_1}) = x^n * poly p x"
by (simp add: poly_monom)
text {* Decomposition of polynomial, skipping zero coefficients
after the first. *}
lemma poly_decompose_lemma:
- assumes nz: "\<not>(\<forall>z. z\<noteq>0 \<longrightarrow> poly p z = (0::'a::{recpower,idom}))"
+ assumes nz: "\<not>(\<forall>z. z\<noteq>0 \<longrightarrow> poly p z = (0::'a::{idom}))"
shows "\<exists>k a q. a\<noteq>0 \<and> Suc (psize q + k) = psize p \<and>
(\<forall>z. poly p z = z^k * poly (pCons a q) z)"
unfolding psize_def
@@ -595,7 +595,7 @@
lemma poly_decompose:
assumes nc: "~constant(poly p)"
- shows "\<exists>k a q. a\<noteq>(0::'a::{recpower,idom}) \<and> k\<noteq>0 \<and>
+ shows "\<exists>k a q. a\<noteq>(0::'a::{idom}) \<and> k\<noteq>0 \<and>
psize q + k + 1 = psize p \<and>
(\<forall>z. poly p z = poly p 0 + z^k * poly (pCons a q) z)"
using nc
--- a/src/HOL/Library/Library.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Library.thy Mon May 11 17:20:52 2009 +0200
@@ -42,6 +42,7 @@
Pocklington
Poly_Deriv
Polynomial
+ Preorder
Primes
Product_Vector
Quickcheck
--- a/src/HOL/Library/Nat_Infinity.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Nat_Infinity.thy Mon May 11 17:20:52 2009 +0200
@@ -24,6 +24,13 @@
Infty ("\<infinity>")
+lemma not_Infty_eq[iff]: "(x ~= Infty) = (EX i. x = Fin i)"
+by (cases x) auto
+
+lemma not_Fin_eq [iff]: "(ALL y. x ~= Fin y) = (x = Infty)"
+by (cases x) auto
+
+
subsection {* Constructors and numbers *}
instantiation inat :: "{zero, one, number}"
@@ -261,6 +268,9 @@
end
+instance inat :: linorder
+by intro_classes (auto simp add: less_eq_inat_def split: inat.splits)
+
instance inat :: pordered_comm_semiring
proof
fix a b c :: inat
@@ -413,4 +423,8 @@
lemmas inat_splits = inat.splits
+
+instance inat :: linorder
+by intro_classes (auto simp add: inat_defs split: inat.splits)
+
end
--- a/src/HOL/Library/Numeral_Type.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Numeral_Type.thy Mon May 11 17:20:52 2009 +0200
@@ -55,7 +55,7 @@
unfolding UNIV_Plus_UNIV [symmetric] by (simp only: finite card_Plus)
lemma card_option [simp]: "CARD('a option) = Suc CARD('a::finite)"
- unfolding insert_None_conv_UNIV [symmetric]
+ unfolding UNIV_option_conv
apply (subgoal_tac "(None::'a option) \<notin> range Some")
apply (simp add: card_image)
apply fast
@@ -154,8 +154,8 @@
locale mod_type =
fixes n :: int
- and Rep :: "'a::{zero,one,plus,times,uminus,minus,power} \<Rightarrow> int"
- and Abs :: "int \<Rightarrow> 'a::{zero,one,plus,times,uminus,minus,power}"
+ and Rep :: "'a::{zero,one,plus,times,uminus,minus} \<Rightarrow> int"
+ and Abs :: "int \<Rightarrow> 'a::{zero,one,plus,times,uminus,minus}"
assumes type: "type_definition Rep Abs {0..<n}"
and size1: "1 < n"
and zero_def: "0 = Abs 0"
@@ -164,14 +164,13 @@
and mult_def: "x * y = Abs ((Rep x * Rep y) mod n)"
and diff_def: "x - y = Abs ((Rep x - Rep y) mod n)"
and minus_def: "- x = Abs ((- Rep x) mod n)"
- and power_def: "x ^ k = Abs (Rep x ^ k mod n)"
begin
lemma size0: "0 < n"
by (cut_tac size1, simp)
lemmas definitions =
- zero_def one_def add_def mult_def minus_def diff_def power_def
+ zero_def one_def add_def mult_def minus_def diff_def
lemma Rep_less_n: "Rep x < n"
by (rule type_definition.Rep [OF type, simplified, THEN conjunct2])
@@ -217,18 +216,12 @@
apply (simp_all add: Rep_simps zmod_simps ring_simps)
done
-lemma recpower: "OFCLASS('a, recpower_class)"
-apply (intro_classes, unfold definitions)
-apply (simp_all add: Rep_simps zmod_simps add_ac mult_assoc
- mod_pos_pos_trivial size1)
-done
-
end
locale mod_ring = mod_type +
constrains n :: int
- and Rep :: "'a::{number_ring,power} \<Rightarrow> int"
- and Abs :: "int \<Rightarrow> 'a::{number_ring,power}"
+ and Rep :: "'a::{number_ring} \<Rightarrow> int"
+ and Abs :: "int \<Rightarrow> 'a::{number_ring}"
begin
lemma of_nat_eq: "of_nat k = Abs (int k mod n)"
@@ -272,7 +265,7 @@
@{typ num1}, since 0 and 1 are not distinct.
*}
-instantiation num1 :: "{comm_ring,comm_monoid_mult,number,recpower}"
+instantiation num1 :: "{comm_ring,comm_monoid_mult,number}"
begin
lemma num1_eq_iff: "(x::num1) = (y::num1) \<longleftrightarrow> True"
@@ -284,7 +277,7 @@
end
instantiation
- bit0 and bit1 :: (finite) "{zero,one,plus,times,uminus,minus,power}"
+ bit0 and bit1 :: (finite) "{zero,one,plus,times,uminus,minus}"
begin
definition Abs_bit0' :: "int \<Rightarrow> 'a bit0" where
@@ -299,7 +292,6 @@
definition "x * y = Abs_bit0' (Rep_bit0 x * Rep_bit0 y)"
definition "x - y = Abs_bit0' (Rep_bit0 x - Rep_bit0 y)"
definition "- x = Abs_bit0' (- Rep_bit0 x)"
-definition "x ^ k = Abs_bit0' (Rep_bit0 x ^ k)"
definition "0 = Abs_bit1 0"
definition "1 = Abs_bit1 1"
@@ -307,7 +299,6 @@
definition "x * y = Abs_bit1' (Rep_bit1 x * Rep_bit1 y)"
definition "x - y = Abs_bit1' (Rep_bit1 x - Rep_bit1 y)"
definition "- x = Abs_bit1' (- Rep_bit1 x)"
-definition "x ^ k = Abs_bit1' (Rep_bit1 x ^ k)"
instance ..
@@ -326,7 +317,6 @@
apply (rule times_bit0_def [unfolded Abs_bit0'_def])
apply (rule minus_bit0_def [unfolded Abs_bit0'_def])
apply (rule uminus_bit0_def [unfolded Abs_bit0'_def])
-apply (rule power_bit0_def [unfolded Abs_bit0'_def])
done
interpretation bit1:
@@ -342,14 +332,13 @@
apply (rule times_bit1_def [unfolded Abs_bit1'_def])
apply (rule minus_bit1_def [unfolded Abs_bit1'_def])
apply (rule uminus_bit1_def [unfolded Abs_bit1'_def])
-apply (rule power_bit1_def [unfolded Abs_bit1'_def])
done
-instance bit0 :: (finite) "{comm_ring_1,recpower}"
- by (rule bit0.comm_ring_1 bit0.recpower)+
+instance bit0 :: (finite) comm_ring_1
+ by (rule bit0.comm_ring_1)+
-instance bit1 :: (finite) "{comm_ring_1,recpower}"
- by (rule bit1.comm_ring_1 bit1.recpower)+
+instance bit1 :: (finite) comm_ring_1
+ by (rule bit1.comm_ring_1)+
instantiation bit0 and bit1 :: (finite) number_ring
begin
@@ -386,9 +375,6 @@
lemmas bit0_iszero_number_of [simp] = bit0.iszero_number_of
lemmas bit1_iszero_number_of [simp] = bit1.iszero_number_of
-declare power_Suc [where ?'a="'a::finite bit0", standard, simp]
-declare power_Suc [where ?'a="'a::finite bit1", standard, simp]
-
subsection {* Syntax *}
--- a/src/HOL/Library/Pocklington.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Pocklington.thy Mon May 11 17:20:52 2009 +0200
@@ -568,7 +568,7 @@
lemma nproduct_cmul:
assumes fS:"finite S"
- shows "setprod (\<lambda>m. (c::'a::{comm_monoid_mult,recpower})* a(m)) S = c ^ (card S) * setprod a S"
+ shows "setprod (\<lambda>m. (c::'a::{comm_monoid_mult})* a(m)) S = c ^ (card S) * setprod a S"
unfolding setprod_timesf setprod_constant[OF fS, of c] ..
lemma coprime_nproduct:
--- a/src/HOL/Library/Polynomial.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Polynomial.thy Mon May 11 17:20:52 2009 +0200
@@ -632,20 +632,6 @@
shows "a \<noteq> 0 \<Longrightarrow> p dvd smult a q \<longleftrightarrow> p dvd q"
by (safe elim!: dvd_smult dvd_smult_cancel)
-instantiation poly :: (comm_semiring_1) recpower
-begin
-
-primrec power_poly where
- "(p::'a poly) ^ 0 = 1"
-| "(p::'a poly) ^ (Suc n) = p * p ^ n"
-
-instance
- by default simp_all
-
-declare power_poly.simps [simp del]
-
-end
-
lemma degree_power_le: "degree (p ^ n) \<le> degree p * n"
by (induct n, simp, auto intro: order_trans degree_mult_le)
@@ -987,6 +973,30 @@
by (simp add: pdivmod_rel_def left_distrib)
thus "(x + z * y) div y = z + x div y"
by (rule div_poly_eq)
+next
+ fix x y z :: "'a poly"
+ assume "x \<noteq> 0"
+ show "(x * y) div (x * z) = y div z"
+ proof (cases "y \<noteq> 0 \<and> z \<noteq> 0")
+ have "\<And>x::'a poly. pdivmod_rel x 0 0 x"
+ by (rule pdivmod_rel_by_0)
+ then have [simp]: "\<And>x::'a poly. x div 0 = 0"
+ by (rule div_poly_eq)
+ have "\<And>x::'a poly. pdivmod_rel 0 x 0 0"
+ by (rule pdivmod_rel_0)
+ then have [simp]: "\<And>x::'a poly. 0 div x = 0"
+ by (rule div_poly_eq)
+ case False then show ?thesis by auto
+ next
+ case True then have "y \<noteq> 0" and "z \<noteq> 0" by auto
+ with `x \<noteq> 0`
+ have "\<And>q r. pdivmod_rel y z q r \<Longrightarrow> pdivmod_rel (x * y) (x * z) q (x * r)"
+ by (auto simp add: pdivmod_rel_def algebra_simps)
+ (rule classical, simp add: degree_mult_eq)
+ moreover from pdivmod_rel have "pdivmod_rel y z (y div z) (y mod z)" .
+ ultimately have "pdivmod_rel (x * y) (x * z) (y div z) (x * (y mod z))" .
+ then show ?thesis by (simp add: div_poly_eq)
+ qed
qed
end
@@ -1108,7 +1118,7 @@
unfolding one_poly_def by simp
lemma poly_monom:
- fixes a x :: "'a::{comm_semiring_1,recpower}"
+ fixes a x :: "'a::{comm_semiring_1}"
shows "poly (monom a n) x = a * x ^ n"
by (induct n, simp add: monom_0, simp add: monom_Suc power_Suc mult_ac)
@@ -1137,7 +1147,7 @@
by (induct p, simp_all, simp add: algebra_simps)
lemma poly_power [simp]:
- fixes p :: "'a::{comm_semiring_1,recpower} poly"
+ fixes p :: "'a::{comm_semiring_1} poly"
shows "poly (p ^ n) x = poly p x ^ n"
by (induct n, simp, simp add: power_Suc)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Library/Preorder.thy Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,65 @@
+(* Author: Florian Haftmann, TU Muenchen *)
+
+header {* Preorders with explicit equivalence relation *}
+
+theory Preorder
+imports Orderings
+begin
+
+class preorder_equiv = preorder
+begin
+
+definition equiv :: "'a \<Rightarrow> 'a \<Rightarrow> bool" where
+ "equiv x y \<longleftrightarrow> x \<le> y \<and> y \<le> x"
+
+notation
+ equiv ("op ~~") and
+ equiv ("(_/ ~~ _)" [51, 51] 50)
+
+notation (xsymbols)
+ equiv ("op \<approx>") and
+ equiv ("(_/ \<approx> _)" [51, 51] 50)
+
+notation (HTML output)
+ equiv ("op \<approx>") and
+ equiv ("(_/ \<approx> _)" [51, 51] 50)
+
+lemma refl [iff]:
+ "x \<approx> x"
+ unfolding equiv_def by simp
+
+lemma trans:
+ "x \<approx> y \<Longrightarrow> y \<approx> z \<Longrightarrow> x \<approx> z"
+ unfolding equiv_def by (auto intro: order_trans)
+
+lemma antisym:
+ "x \<le> y \<Longrightarrow> y \<le> x \<Longrightarrow> x \<approx> y"
+ unfolding equiv_def ..
+
+lemma less_le: "x < y \<longleftrightarrow> x \<le> y \<and> \<not> x \<approx> y"
+ by (auto simp add: equiv_def less_le_not_le)
+
+lemma le_less: "x \<le> y \<longleftrightarrow> x < y \<or> x \<approx> y"
+ by (auto simp add: equiv_def less_le)
+
+lemma le_imp_less_or_eq: "x \<le> y \<Longrightarrow> x < y \<or> x \<approx> y"
+ by (simp add: less_le)
+
+lemma less_imp_not_eq: "x < y \<Longrightarrow> x \<approx> y \<longleftrightarrow> False"
+ by (simp add: less_le)
+
+lemma less_imp_not_eq2: "x < y \<Longrightarrow> y \<approx> x \<longleftrightarrow> False"
+ by (simp add: equiv_def less_le)
+
+lemma neq_le_trans: "\<not> a \<approx> b \<Longrightarrow> a \<le> b \<Longrightarrow> a < b"
+ by (simp add: less_le)
+
+lemma le_neq_trans: "a \<le> b \<Longrightarrow> \<not> a \<approx> b \<Longrightarrow> a < b"
+ by (simp add: less_le)
+
+lemma antisym_conv: "y \<le> x \<Longrightarrow> x \<le> y \<longleftrightarrow> x \<approx> y"
+ by (simp add: equiv_def)
+
+end
+
+end
--- a/src/HOL/Library/Primes.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Primes.thy Mon May 11 17:20:52 2009 +0200
@@ -454,19 +454,11 @@
qed
lemma euclid: "\<exists>p. prime p \<and> p > n" using euclid_bound by auto
+
lemma primes_infinite: "\<not> (finite {p. prime p})"
-proof (auto simp add: finite_conv_nat_seg_image)
- fix n f
- assume H: "Collect prime = f ` {i. i < (n::nat)}"
- let ?P = "Collect prime"
- let ?m = "Max ?P"
- have P0: "?P \<noteq> {}" using two_is_prime by auto
- from H have fP: "finite ?P" using finite_conv_nat_seg_image by blast
- from Max_in [OF fP P0] have "?m \<in> ?P" .
- from Max_ge [OF fP] have contr: "\<forall> p. prime p \<longrightarrow> p \<le> ?m" by blast
- from euclid [of ?m] obtain q where q: "prime q" "q > ?m" by blast
- with contr show False by auto
-qed
+apply(simp add: finite_nat_set_iff_bounded_le)
+apply (metis euclid linorder_not_le)
+done
lemma coprime_prime: assumes ab: "coprime a b"
shows "~(prime p \<and> p dvd a \<and> p dvd b)"
--- a/src/HOL/Library/Product_ord.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Product_ord.thy Mon May 11 17:20:52 2009 +0200
@@ -12,25 +12,28 @@
begin
definition
- prod_le_def [code del]: "x \<le> y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x \<le> snd y"
+ prod_le_def [code del]: "x \<le> y \<longleftrightarrow> fst x < fst y \<or> fst x \<le> fst y \<and> snd x \<le> snd y"
definition
- prod_less_def [code del]: "x < y \<longleftrightarrow> fst x < fst y \<or> fst x = fst y \<and> snd x < snd y"
+ prod_less_def [code del]: "x < y \<longleftrightarrow> fst x < fst y \<or> fst x \<le> fst y \<and> snd x < snd y"
instance ..
end
lemma [code]:
- "(x1\<Colon>'a\<Colon>{ord, eq}, y1) \<le> (x2, y2) \<longleftrightarrow> x1 < x2 \<or> x1 = x2 \<and> y1 \<le> y2"
- "(x1\<Colon>'a\<Colon>{ord, eq}, y1) < (x2, y2) \<longleftrightarrow> x1 < x2 \<or> x1 = x2 \<and> y1 < y2"
+ "(x1\<Colon>'a\<Colon>{ord, eq}, y1) \<le> (x2, y2) \<longleftrightarrow> x1 < x2 \<or> x1 \<le> x2 \<and> y1 \<le> y2"
+ "(x1\<Colon>'a\<Colon>{ord, eq}, y1) < (x2, y2) \<longleftrightarrow> x1 < x2 \<or> x1 \<le> x2 \<and> y1 < y2"
unfolding prod_le_def prod_less_def by simp_all
-instance * :: (order, order) order
- by default (auto simp: prod_le_def prod_less_def intro: order_less_trans)
+instance * :: (preorder, preorder) preorder proof
+qed (auto simp: prod_le_def prod_less_def less_le_not_le intro: order_trans)
-instance * :: (linorder, linorder) linorder
- by default (auto simp: prod_le_def)
+instance * :: (order, order) order proof
+qed (auto simp add: prod_le_def)
+
+instance * :: (linorder, linorder) linorder proof
+qed (auto simp: prod_le_def)
instantiation * :: (linorder, linorder) distrib_lattice
begin
@@ -41,9 +44,30 @@
definition
sup_prod_def: "(sup \<Colon> 'a \<times> 'b \<Rightarrow> _ \<Rightarrow> _) = max"
-instance
- by intro_classes
- (auto simp add: inf_prod_def sup_prod_def min_max.sup_inf_distrib1)
+instance proof
+qed (auto simp add: inf_prod_def sup_prod_def min_max.sup_inf_distrib1)
+
+end
+
+instantiation * :: (bot, bot) bot
+begin
+
+definition
+ bot_prod_def: "bot = (bot, bot)"
+
+instance proof
+qed (auto simp add: bot_prod_def prod_le_def)
+
+end
+
+instantiation * :: (top, top) top
+begin
+
+definition
+ top_prod_def: "top = (top, top)"
+
+instance proof
+qed (auto simp add: top_prod_def prod_le_def)
end
--- a/src/HOL/Library/Quickcheck.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Quickcheck.thy Mon May 11 17:20:52 2009 +0200
@@ -47,6 +47,8 @@
val eval_ref : (unit -> int -> int * int -> term list option * (int * int)) option ref = ref NONE;
+val target = "Quickcheck";
+
fun mk_generator_expr thy prop tys =
let
val bound_max = length tys - 1;
@@ -72,14 +74,75 @@
let
val tys = (map snd o fst o strip_abs) t;
val t' = mk_generator_expr thy t tys;
- val f = Code_ML.eval_term ("Quickcheck.eval_ref", eval_ref) thy t' [];
- in f #> Random_Engine.run #> (Option.map o map) (Code.postprocess_term thy) end;
+ val f = Code_ML.eval (SOME target) ("Quickcheck.eval_ref", eval_ref)
+ (fn proc => fn g => fn s => g s #>> (Option.map o map) proc) thy t' [];
+ in f #> Random_Engine.run end;
end
*}
setup {*
- Quickcheck.add_generator ("code", Quickcheck.compile_generator_expr o ProofContext.theory_of)
+ Code_Target.extend_target (Quickcheck.target, (Code_ML.target_Eval, K I))
+ #> Quickcheck.add_generator ("code", Quickcheck.compile_generator_expr o ProofContext.theory_of)
*}
+
+subsection {* Type @{typ "'a \<Rightarrow> 'b"} *}
+
+ML {*
+structure Random_Engine =
+struct
+
+open Random_Engine;
+
+fun random_fun (T1 : typ) (T2 : typ) (eq : 'a -> 'a -> bool) (term_of : 'a -> term)
+ (random : Random_Engine.seed -> ('b * (unit -> term)) * Random_Engine.seed)
+ (random_split : Random_Engine.seed -> Random_Engine.seed * Random_Engine.seed)
+ (seed : Random_Engine.seed) =
+ let
+ val (seed', seed'') = random_split seed;
+ val state = ref (seed', [], Const (@{const_name undefined}, T1 --> T2));
+ val fun_upd = Const (@{const_name fun_upd},
+ (T1 --> T2) --> T1 --> T2 --> T1 --> T2);
+ fun random_fun' x =
+ let
+ val (seed, fun_map, f_t) = ! state;
+ in case AList.lookup (uncurry eq) fun_map x
+ of SOME y => y
+ | NONE => let
+ val t1 = term_of x;
+ val ((y, t2), seed') = random seed;
+ val fun_map' = (x, y) :: fun_map;
+ val f_t' = fun_upd $ f_t $ t1 $ t2 ();
+ val _ = state := (seed', fun_map', f_t');
+ in y end
+ end;
+ fun term_fun' () = #3 (! state);
+ in ((random_fun', term_fun'), seed'') end;
+
end
+*}
+
+axiomatization
+ random_fun_aux :: "typerep \<Rightarrow> typerep \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> term)
+ \<Rightarrow> (seed \<Rightarrow> ('b \<times> (unit \<Rightarrow> term)) \<times> seed) \<Rightarrow> (seed \<Rightarrow> seed \<times> seed)
+ \<Rightarrow> seed \<Rightarrow> (('a \<Rightarrow> 'b) \<times> (unit \<Rightarrow> term)) \<times> seed"
+
+code_const random_fun_aux (Quickcheck "Random'_Engine.random'_fun")
+ -- {* With enough criminal energy this can be abused to derive @{prop False};
+ for this reason we use a distinguished target @{text Quickcheck}
+ not spoiling the regular trusted code generation *}
+
+instantiation "fun" :: ("{eq, term_of}", "{type, random}") random
+begin
+
+definition random_fun :: "index \<Rightarrow> seed \<Rightarrow> (('a \<Rightarrow> 'b) \<times> (unit \<Rightarrow> term)) \<times> seed" where
+ "random n = random_fun_aux TYPEREP('a) TYPEREP('b) (op =) Code_Eval.term_of (random n) split_seed"
+
+instance ..
+
+end
+
+code_reserved Quickcheck Random_Engine
+
+end
--- a/src/HOL/Library/State_Monad.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/State_Monad.thy Mon May 11 17:20:52 2009 +0200
@@ -190,7 +190,7 @@
*}
text {*
- For an example, see HOL/ex/Random.thy.
+ For an example, see HOL/Extraction/Higman.thy.
*}
end
--- a/src/HOL/Library/Topology_Euclidean_Space.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Topology_Euclidean_Space.thy Mon May 11 17:20:52 2009 +0200
@@ -5441,7 +5441,7 @@
have "1 - c > 0" using c by auto
from s(2) obtain z0 where "z0 \<in> s" by auto
- def z \<equiv> "\<lambda> n::nat. fun_pow n f z0"
+ def z \<equiv> "\<lambda>n. (f ^^ n) z0"
{ fix n::nat
have "z n \<in> s" unfolding z_def
proof(induct n) case 0 thus ?case using `z0 \<in>s` by auto
@@ -5580,7 +5580,7 @@
using dist[THEN bspec[where x=x], THEN bspec[where x=y]] by auto } note dist' = this
def y \<equiv> "g x"
have [simp]:"y\<in>s" unfolding y_def using gs[unfolded image_subset_iff] and `x\<in>s` by blast
- def f \<equiv> "\<lambda> n. fun_pow n g"
+ def f \<equiv> "\<lambda>n. g ^^ n"
have [simp]:"\<And>n z. g (f n z) = f (Suc n) z" unfolding f_def by auto
have [simp]:"\<And>z. f 0 z = z" unfolding f_def by auto
{ fix n::nat and z assume "z\<in>s"
--- a/src/HOL/Library/Univ_Poly.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Univ_Poly.thy Mon May 11 17:20:52 2009 +0200
@@ -167,22 +167,9 @@
simp_all add: poly_cmult poly_add left_distrib right_distrib mult_ac)
qed
-class recpower_semiring = semiring + recpower
-class recpower_semiring_1 = semiring_1 + recpower
-class recpower_semiring_0 = semiring_0 + recpower
-class recpower_ring = ring + recpower
-class recpower_ring_1 = ring_1 + recpower
-subclass (in recpower_ring_1) recpower_ring ..
-class recpower_comm_semiring_1 = recpower + comm_semiring_1
-class recpower_comm_ring_1 = recpower + comm_ring_1
-subclass (in recpower_comm_ring_1) recpower_comm_semiring_1 ..
-class recpower_idom = recpower + idom
-subclass (in recpower_idom) recpower_comm_ring_1 ..
class idom_char_0 = idom + ring_char_0
-class recpower_idom_char_0 = recpower + idom_char_0
-subclass (in recpower_idom_char_0) recpower_idom ..
-lemma (in recpower_comm_ring_1) poly_exp: "poly (p %^ n) x = (poly p x) ^ n"
+lemma (in comm_ring_1) poly_exp: "poly (p %^ n) x = (poly p x) ^ n"
apply (induct "n")
apply (auto simp add: poly_cmult poly_mult power_Suc)
done
@@ -418,7 +405,7 @@
finally show ?thesis .
qed
-lemma (in recpower_idom) poly_exp_eq_zero[simp]:
+lemma (in idom) poly_exp_eq_zero[simp]:
"(poly (p %^ n) = poly []) = (poly p = poly [] & n \<noteq> 0)"
apply (simp only: fun_eq add: all_simps [symmetric])
apply (rule arg_cong [where f = All])
@@ -437,7 +424,7 @@
apply simp
done
-lemma (in recpower_idom) poly_exp_prime_eq_zero: "(poly ([a, 1] %^ n) \<noteq> poly [])"
+lemma (in idom) poly_exp_prime_eq_zero: "(poly ([a, 1] %^ n) \<noteq> poly [])"
by auto
text{*A more constructive notion of polynomials being trivial*}
@@ -507,7 +494,7 @@
done
-lemma (in recpower_comm_semiring_1) poly_divides_exp: "m \<le> n ==> (p %^ m) divides (p %^ n)"
+lemma (in comm_semiring_1) poly_divides_exp: "m \<le> n ==> (p %^ m) divides (p %^ n)"
apply (auto simp add: le_iff_add)
apply (induct_tac k)
apply (rule_tac [2] poly_divides_trans)
@@ -516,7 +503,7 @@
apply (auto simp add: poly_mult fun_eq mult_ac)
done
-lemma (in recpower_comm_semiring_1) poly_exp_divides: "[| (p %^ n) divides q; m\<le>n |] ==> (p %^ m) divides q"
+lemma (in comm_semiring_1) poly_exp_divides: "[| (p %^ n) divides q; m\<le>n |] ==> (p %^ m) divides q"
by (blast intro: poly_divides_exp poly_divides_trans)
lemma (in comm_semiring_0) poly_divides_add:
@@ -583,7 +570,7 @@
qed
-lemma (in recpower_comm_semiring_1) poly_mulexp: "poly (mulexp n p q) x = (poly p x) ^ n * poly q x"
+lemma (in comm_semiring_1) poly_mulexp: "poly (mulexp n p q) x = (poly p x) ^ n * poly q x"
by(induct n, auto simp add: poly_mult power_Suc mult_ac)
lemma (in comm_semiring_1) divides_left_mult:
@@ -600,11 +587,11 @@
(* FIXME: Tidy up *)
-lemma (in recpower_semiring_1)
+lemma (in semiring_1)
zero_power_iff: "0 ^ n = (if n = 0 then 1 else 0)"
by (induct n, simp_all add: power_Suc)
-lemma (in recpower_idom_char_0) poly_order_exists:
+lemma (in idom_char_0) poly_order_exists:
assumes lp: "length p = d" and p0: "poly p \<noteq> poly []"
shows "\<exists>n. ([-a, 1] %^ n) divides p & ~(([-a, 1] %^ (Suc n)) divides p)"
proof-
@@ -637,7 +624,7 @@
lemma (in semiring_1) poly_one_divides[simp]: "[1] divides p"
by (simp add: divides_def, auto)
-lemma (in recpower_idom_char_0) poly_order: "poly p \<noteq> poly []
+lemma (in idom_char_0) poly_order: "poly p \<noteq> poly []
==> EX! n. ([-a, 1] %^ n) divides p &
~(([-a, 1] %^ (Suc n)) divides p)"
apply (auto intro: poly_order_exists simp add: less_linear simp del: pmult_Cons pexp_Suc)
@@ -652,7 +639,7 @@
lemma some1_equalityD: "[| n = (@n. P n); EX! n. P n |] ==> P n"
by (blast intro: someI2)
-lemma (in recpower_idom_char_0) order:
+lemma (in idom_char_0) order:
"(([-a, 1] %^ n) divides p &
~(([-a, 1] %^ (Suc n)) divides p)) =
((n = order a p) & ~(poly p = poly []))"
@@ -662,17 +649,17 @@
apply (blast intro!: poly_order [THEN [2] some1_equalityD])
done
-lemma (in recpower_idom_char_0) order2: "[| poly p \<noteq> poly [] |]
+lemma (in idom_char_0) order2: "[| poly p \<noteq> poly [] |]
==> ([-a, 1] %^ (order a p)) divides p &
~(([-a, 1] %^ (Suc(order a p))) divides p)"
by (simp add: order del: pexp_Suc)
-lemma (in recpower_idom_char_0) order_unique: "[| poly p \<noteq> poly []; ([-a, 1] %^ n) divides p;
+lemma (in idom_char_0) order_unique: "[| poly p \<noteq> poly []; ([-a, 1] %^ n) divides p;
~(([-a, 1] %^ (Suc n)) divides p)
|] ==> (n = order a p)"
by (insert order [of a n p], auto)
-lemma (in recpower_idom_char_0) order_unique_lemma: "(poly p \<noteq> poly [] & ([-a, 1] %^ n) divides p &
+lemma (in idom_char_0) order_unique_lemma: "(poly p \<noteq> poly [] & ([-a, 1] %^ n) divides p &
~(([-a, 1] %^ (Suc n)) divides p))
==> (n = order a p)"
by (blast intro: order_unique)
@@ -692,7 +679,7 @@
apply (auto simp add: divides_def poly_mult simp del: pmult_Cons)
done
-lemma (in recpower_idom_char_0) order_root: "(poly p a = 0) = ((poly p = poly []) | order a p \<noteq> 0)"
+lemma (in idom_char_0) order_root: "(poly p a = 0) = ((poly p = poly []) | order a p \<noteq> 0)"
proof-
let ?poly = poly
show ?thesis
@@ -706,7 +693,7 @@
done
qed
-lemma (in recpower_idom_char_0) order_divides: "(([-a, 1] %^ n) divides p) = ((poly p = poly []) | n \<le> order a p)"
+lemma (in idom_char_0) order_divides: "(([-a, 1] %^ n) divides p) = ((poly p = poly []) | n \<le> order a p)"
proof-
let ?poly = poly
show ?thesis
@@ -718,7 +705,7 @@
done
qed
-lemma (in recpower_idom_char_0) order_decomp:
+lemma (in idom_char_0) order_decomp:
"poly p \<noteq> poly []
==> \<exists>q. (poly p = poly (([-a, 1] %^ (order a p)) *** q)) &
~([-a, 1] divides q)"
@@ -732,7 +719,7 @@
text{*Important composition properties of orders.*}
lemma order_mult: "poly (p *** q) \<noteq> poly []
- ==> order a (p *** q) = order a p + order (a::'a::{recpower_idom_char_0}) q"
+ ==> order a (p *** q) = order a p + order (a::'a::{idom_char_0}) q"
apply (cut_tac a = a and p = "p *** q" and n = "order a p + order a q" in order)
apply (auto simp add: poly_entire simp del: pmult_Cons)
apply (drule_tac a = a in order2)+
@@ -753,7 +740,7 @@
apply (simp add: fun_eq poly_exp_add poly_mult mult_ac del: pmult_Cons)
done
-lemma (in recpower_idom_char_0) order_mult:
+lemma (in idom_char_0) order_mult:
assumes pq0: "poly (p *** q) \<noteq> poly []"
shows "order a (p *** q) = order a p + order a q"
proof-
@@ -783,7 +770,7 @@
done
qed
-lemma (in recpower_idom_char_0) order_root2: "poly p \<noteq> poly [] ==> (poly p a = 0) = (order a p \<noteq> 0)"
+lemma (in idom_char_0) order_root2: "poly p \<noteq> poly [] ==> (poly p a = 0) = (order a p \<noteq> 0)"
by (rule order_root [THEN ssubst], auto)
lemma (in semiring_1) pmult_one[simp]: "[1] *** p = p" by auto
@@ -791,7 +778,7 @@
lemma (in semiring_0) poly_Nil_zero: "poly [] = poly [0]"
by (simp add: fun_eq)
-lemma (in recpower_idom_char_0) rsquarefree_decomp:
+lemma (in idom_char_0) rsquarefree_decomp:
"[| rsquarefree p; poly p a = 0 |]
==> \<exists>q. (poly p = poly ([-a, 1] *** q)) & poly q a \<noteq> 0"
apply (simp add: rsquarefree_def, safe)
@@ -999,7 +986,7 @@
ultimately show ?case by blast
qed
-lemma (in recpower_idom_char_0) order_degree:
+lemma (in idom_char_0) order_degree:
assumes p0: "poly p \<noteq> poly []"
shows "order a p \<le> degree p"
proof-
--- a/src/HOL/Library/Word.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/Word.thy Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title: HOL/Library/Word.thy
- ID: $Id$
Author: Sebastian Skalberg (TU Muenchen)
*)
@@ -40,10 +39,8 @@
Zero ("\<zero>")
| One ("\<one>")
-primrec
- bitval :: "bit => nat"
-where
- "bitval \<zero> = 0"
+primrec bitval :: "bit => nat" where
+ "bitval \<zero> = 0"
| "bitval \<one> = 1"
consts
@@ -1531,7 +1528,7 @@
show ?thesis
apply simp
apply (subst power_Suc [symmetric])
- apply (simp del: power_int.simps)
+ apply simp
done
qed
finally show ?thesis .
--- a/src/HOL/Library/comm_ring.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/comm_ring.ML Mon May 11 17:20:52 2009 +0200
@@ -65,7 +65,7 @@
| reif_polex T vs t = polex_pol T $ reif_pol T vs t;
(* reification of the equation *)
-val TFree (_, cr_sort) = @{typ "'a :: {comm_ring, recpower}"};
+val cr_sort = @{sort "comm_ring_1"};
fun reif_eq thy (eq as Const("op =", Type("fun", [T, _])) $ lhs $ rhs) =
if Sign.of_sort thy (T, cr_sort) then
--- a/src/HOL/Library/reflection.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Library/reflection.ML Mon May 11 17:20:52 2009 +0200
@@ -314,5 +314,6 @@
in (rtac th i THEN TRY(rtac TrueI i)) st end);
fun reflection_tac ctxt = gen_reflection_tac ctxt Codegen.evaluation_conv;
+ (*FIXME why Codegen.evaluation_conv? very specific...*)
end
--- a/src/HOL/Lim.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Lim.thy Mon May 11 17:20:52 2009 +0200
@@ -383,7 +383,7 @@
lemmas LIM_of_real = of_real.LIM
lemma LIM_power:
- fixes f :: "'a::real_normed_vector \<Rightarrow> 'b::{recpower,real_normed_algebra}"
+ fixes f :: "'a::real_normed_vector \<Rightarrow> 'b::{power,real_normed_algebra}"
assumes f: "f -- a --> l"
shows "(\<lambda>x. f x ^ n) -- a --> l ^ n"
by (induct n, simp, simp add: LIM_mult f)
@@ -530,7 +530,7 @@
unfolding isCont_def by (rule LIM_of_real)
lemma isCont_power:
- fixes f :: "'a::real_normed_vector \<Rightarrow> 'b::{recpower,real_normed_algebra}"
+ fixes f :: "'a::real_normed_vector \<Rightarrow> 'b::{power,real_normed_algebra}"
shows "isCont f a \<Longrightarrow> isCont (\<lambda>x. f x ^ n) a"
unfolding isCont_def by (rule LIM_power)
--- a/src/HOL/List.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/List.thy Mon May 11 17:20:52 2009 +0200
@@ -5,8 +5,8 @@
header {* The datatype of finite lists *}
theory List
-imports Plain Relation_Power Presburger Recdef ATP_Linkup
-uses "Tools/string_syntax.ML"
+imports Plain Presburger Recdef ATP_Linkup
+uses ("Tools/list_code.ML")
begin
datatype 'a list =
@@ -198,7 +198,7 @@
definition
rotate :: "nat \<Rightarrow> 'a list \<Rightarrow> 'a list" where
- "rotate n = rotate1 ^ n"
+ "rotate n = rotate1 ^^ n"
definition
list_all2 :: "('a => 'b => bool) => 'a list => 'b list => bool" where
@@ -1324,6 +1324,9 @@
apply simp_all
done
+lemma list_update_nonempty[simp]: "xs[k:=x] = [] \<longleftrightarrow> xs=[]"
+by(metis length_0_conv length_list_update)
+
lemma list_update_same_conv:
"i < length xs ==> (xs[i := x] = xs) = (xs!i = x)"
by (induct xs arbitrary: i) (auto split: nat.split)
@@ -1344,8 +1347,7 @@
by (induct xs, auto)
lemma update_zip:
- "length xs = length ys ==>
- (zip xs ys)[i:=xy] = zip (xs[i:=fst xy]) (ys[i:=snd xy])"
+ "(zip xs ys)[i:=xy] = zip (xs[i:=fst xy]) (ys[i:=snd xy])"
by (induct ys arbitrary: i xy xs) (auto, case_tac xs, auto split: nat.split)
lemma set_update_subset_insert: "set(xs[i:=x]) <= insert x (set xs)"
@@ -1357,12 +1359,10 @@
lemma set_update_memI: "n < length xs \<Longrightarrow> x \<in> set (xs[n := x])"
by (induct xs arbitrary: n) (auto split:nat.splits)
-lemma list_update_overwrite:
+lemma list_update_overwrite[simp]:
"xs [i := x, i := y] = xs [i := y]"
-apply (induct xs arbitrary: i)
-apply simp
-apply (case_tac i)
-apply simp_all
+apply (induct xs arbitrary: i) apply simp
+apply (case_tac i, simp_all)
done
lemma list_update_swap:
@@ -1444,6 +1444,18 @@
lemma butlast_conv_take: "butlast xs = take (length xs - 1) xs"
by (induct xs, simp, case_tac xs, simp_all)
+lemma last_list_update:
+ "xs \<noteq> [] \<Longrightarrow> last(xs[k:=x]) = (if k = size xs - 1 then x else last xs)"
+by (auto simp: last_conv_nth)
+
+lemma butlast_list_update:
+ "butlast(xs[k:=x]) =
+ (if k = size xs - 1 then butlast xs else (butlast xs)[k:=x])"
+apply(cases xs rule:rev_cases)
+apply simp
+apply(simp add:list_update_append split:nat.splits)
+done
+
subsubsection {* @{text take} and @{text drop} *}
@@ -1723,6 +1735,13 @@
"(dropWhile P xs = y#ys) = (xs = takeWhile P xs @ y # ys & \<not> P y)"
by(induct xs, auto)
+lemma distinct_takeWhile[simp]: "distinct xs ==> distinct (takeWhile P xs)"
+by (induct xs) (auto dest: set_takeWhileD)
+
+lemma distinct_dropWhile[simp]: "distinct xs ==> distinct (dropWhile P xs)"
+by (induct xs) auto
+
+
text{* The following two lemmmas could be generalized to an arbitrary
property. *}
@@ -1809,6 +1828,10 @@
apply simp_all
done
+text{* Courtesy of Andreas Lochbihler: *}
+lemma zip_same_conv_map: "zip xs xs = map (\<lambda>x. (x, x)) xs"
+by(induct xs) auto
+
lemma nth_zip [simp]:
"[| i < length xs; i < length ys|] ==> (zip xs ys)!i = (xs!i, ys!i)"
apply (induct ys arbitrary: i xs, simp)
@@ -1818,11 +1841,11 @@
lemma set_zip:
"set (zip xs ys) = {(xs!i, ys!i) | i. i < min (length xs) (length ys)}"
-by (simp add: set_conv_nth cong: rev_conj_cong)
+by(simp add: set_conv_nth cong: rev_conj_cong)
lemma zip_update:
-"length xs = length ys ==> zip (xs[i:=x]) (ys[i:=y]) = (zip xs ys)[i:=(x,y)]"
-by (rule sym, simp add: update_zip)
+ "zip (xs[i:=x]) (ys[i:=y]) = (zip xs ys)[i:=(x,y)]"
+by(rule sym, simp add: update_zip)
lemma zip_replicate [simp]:
"zip (replicate i x) (replicate j y) = replicate (min i j) (x,y)"
@@ -2120,6 +2143,15 @@
shows "listsum (rev xs) = listsum xs"
by (induct xs) (simp_all add:add_ac)
+lemma listsum_map_remove1:
+fixes f :: "'a \<Rightarrow> ('b::comm_monoid_add)"
+shows "x : set xs \<Longrightarrow> listsum(map f xs) = f x + listsum(map f (remove1 x xs))"
+by (induct xs)(auto simp add:add_ac)
+
+lemma list_size_conv_listsum:
+ "list_size f xs = listsum (map f xs) + size xs"
+by(induct xs) auto
+
lemma listsum_foldr: "listsum xs = foldr (op +) xs 0"
by (induct xs) auto
@@ -2131,6 +2163,10 @@
lemma listsum[code unfold]: "listsum xs = foldl (op +) 0 xs"
by(simp add:listsum_foldr foldl_foldr1)
+lemma distinct_listsum_conv_Setsum:
+ "distinct xs \<Longrightarrow> listsum xs = Setsum(set xs)"
+by (induct xs) simp_all
+
text{* Some syntactic sugar for summing a function over a list: *}
@@ -2544,6 +2580,11 @@
apply (simp add: add_commute)
done
+text{* Courtesy of Andreas Lochbihler: *}
+lemma filter_replicate:
+ "filter P (replicate n x) = (if P x then replicate n x else [])"
+by(induct n) auto
+
lemma hd_replicate [simp]: "n \<noteq> 0 ==> hd (replicate n x) = x"
by (induct n) auto
@@ -3424,77 +3465,6 @@
by (auto simp add: set_Cons_def intro: listrel.intros)
-subsection{*Miscellany*}
-
-subsubsection {* Characters and strings *}
-
-datatype nibble =
- Nibble0 | Nibble1 | Nibble2 | Nibble3 | Nibble4 | Nibble5 | Nibble6 | Nibble7
- | Nibble8 | Nibble9 | NibbleA | NibbleB | NibbleC | NibbleD | NibbleE | NibbleF
-
-lemma UNIV_nibble:
- "UNIV = {Nibble0, Nibble1, Nibble2, Nibble3, Nibble4, Nibble5, Nibble6, Nibble7,
- Nibble8, Nibble9, NibbleA, NibbleB, NibbleC, NibbleD, NibbleE, NibbleF}" (is "_ = ?A")
-proof (rule UNIV_eq_I)
- fix x show "x \<in> ?A" by (cases x) simp_all
-qed
-
-instance nibble :: finite
- by default (simp add: UNIV_nibble)
-
-datatype char = Char nibble nibble
- -- "Note: canonical order of character encoding coincides with standard term ordering"
-
-lemma UNIV_char:
- "UNIV = image (split Char) (UNIV \<times> UNIV)"
-proof (rule UNIV_eq_I)
- fix x show "x \<in> image (split Char) (UNIV \<times> UNIV)" by (cases x) auto
-qed
-
-instance char :: finite
- by default (simp add: UNIV_char)
-
-lemma size_char [code, simp]:
- "size (c::char) = 0" by (cases c) simp
-
-lemma char_size [code, simp]:
- "char_size (c::char) = 0" by (cases c) simp
-
-primrec nibble_pair_of_char :: "char \<Rightarrow> nibble \<times> nibble" where
- "nibble_pair_of_char (Char n m) = (n, m)"
-
-declare nibble_pair_of_char.simps [code del]
-
-setup {*
-let
- val nibbles = map (Thm.cterm_of @{theory} o HOLogic.mk_nibble) (0 upto 15);
- val thms = map_product
- (fn n => fn m => Drule.instantiate' [] [SOME n, SOME m] @{thm nibble_pair_of_char.simps})
- nibbles nibbles;
-in
- PureThy.note_thmss Thm.lemmaK [((Binding.name "nibble_pair_of_char_simps", []), [(thms, [])])]
- #-> (fn [(_, thms)] => fold_rev Code.add_eqn thms)
-end
-*}
-
-lemma char_case_nibble_pair [code, code inline]:
- "char_case f = split f o nibble_pair_of_char"
- by (simp add: expand_fun_eq split: char.split)
-
-lemma char_rec_nibble_pair [code, code inline]:
- "char_rec f = split f o nibble_pair_of_char"
- unfolding char_case_nibble_pair [symmetric]
- by (simp add: expand_fun_eq split: char.split)
-
-types string = "char list"
-
-syntax
- "_Char" :: "xstr => char" ("CHR _")
- "_String" :: "xstr => string" ("_")
-
-setup StringSyntax.setup
-
-
subsection {* Size function *}
lemma [measure_function]: "is_measure f \<Longrightarrow> is_measure (list_size f)"
@@ -3518,10 +3488,35 @@
"(\<And>x. x \<in> set xs \<Longrightarrow> f x < g x) \<Longrightarrow> list_size f xs \<le> list_size g xs"
by (induct xs) force+
+
subsection {* Code generator *}
subsubsection {* Setup *}
+use "Tools/list_code.ML"
+
+code_type list
+ (SML "_ list")
+ (OCaml "_ list")
+ (Haskell "![_]")
+
+code_const Nil
+ (SML "[]")
+ (OCaml "[]")
+ (Haskell "[]")
+
+code_instance list :: eq
+ (Haskell -)
+
+code_const "eq_class.eq \<Colon> 'a\<Colon>eq list \<Rightarrow> 'a list \<Rightarrow> bool"
+ (Haskell infixl 4 "==")
+
+code_reserved SML
+ list
+
+code_reserved OCaml
+ list
+
types_code
"list" ("_ list")
attach (term_of) {*
@@ -3537,206 +3532,23 @@
(1, fn () => ([], fn () => HOLogic.nil_const aT))] ()
and gen_list aG aT i = gen_list' aG aT i i;
*}
- "char" ("string")
-attach (term_of) {*
-val term_of_char = HOLogic.mk_char o ord;
-*}
-attach (test) {*
-fun gen_char i =
- let val j = random_range (ord "a") (Int.min (ord "a" + i, ord "z"))
- in (chr j, fn () => HOLogic.mk_char j) end;
-*}
-
-consts_code "Cons" ("(_ ::/ _)")
-
-code_type list
- (SML "_ list")
- (OCaml "_ list")
- (Haskell "![_]")
-
-code_reserved SML
- list
-
-code_reserved OCaml
- list
-
-code_const Nil
- (SML "[]")
- (OCaml "[]")
- (Haskell "[]")
-
-ML {*
-local
-
-open Basic_Code_Thingol;
-
-fun implode_list naming t = case pairself
- (Code_Thingol.lookup_const naming) (@{const_name Nil}, @{const_name Cons})
- of (SOME nil', SOME cons') => let
- fun dest_cons (IConst (c, _) `$ t1 `$ t2) =
- if c = cons'
- then SOME (t1, t2)
- else NONE
- | dest_cons _ = NONE;
- val (ts, t') = Code_Thingol.unfoldr dest_cons t;
- in case t'
- of IConst (c, _) => if c = nil' then SOME ts else NONE
- | _ => NONE
- end
- | _ => NONE
-
-fun decode_char naming (IConst (c1, _), IConst (c2, _)) = (case map_filter
- (Code_Thingol.lookup_const naming)[@{const_name Nibble0}, @{const_name Nibble1},
- @{const_name Nibble2}, @{const_name Nibble3},
- @{const_name Nibble4}, @{const_name Nibble5},
- @{const_name Nibble6}, @{const_name Nibble7},
- @{const_name Nibble8}, @{const_name Nibble9},
- @{const_name NibbleA}, @{const_name NibbleB},
- @{const_name NibbleC}, @{const_name NibbleD},
- @{const_name NibbleE}, @{const_name NibbleF}]
- of nibbles' as [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => let
- fun idx c = find_index (curry (op =) c) nibbles';
- fun decode ~1 _ = NONE
- | decode _ ~1 = NONE
- | decode n m = SOME (chr (n * 16 + m));
- in decode (idx c1) (idx c2) end
- | _ => NONE)
- | decode_char _ _ = NONE
-
-fun implode_string naming mk_char mk_string ts = case
- Code_Thingol.lookup_const naming @{const_name Char}
- of SOME char' => let
- fun implode_char (IConst (c, _) `$ t1 `$ t2) =
- if c = char' then decode_char naming (t1, t2) else NONE
- | implode_char _ = NONE;
- val ts' = map implode_char ts;
- in if forall is_some ts'
- then (SOME o Code_Printer.str o mk_string o implode o map_filter I) ts'
- else NONE
- end
- | _ => NONE;
-
-fun default_list (target_fxy, target_cons) pr fxy t1 t2 =
- Code_Printer.brackify_infix (target_fxy, Code_Printer.R) fxy [
- pr (Code_Printer.INFX (target_fxy, Code_Printer.X)) t1,
- Code_Printer.str target_cons,
- pr (Code_Printer.INFX (target_fxy, Code_Printer.R)) t2
- ];
-
-fun pretty_list literals =
- let
- val mk_list = Code_Printer.literal_list literals;
- fun pretty pr naming thm vars fxy [(t1, _), (t2, _)] =
- case Option.map (cons t1) (implode_list naming t2)
- of SOME ts => mk_list (map (pr vars Code_Printer.NOBR) ts)
- | NONE => default_list (Code_Printer.infix_cons literals) (pr vars) fxy t1 t2;
- in (2, pretty) end;
-
-fun pretty_list_string literals =
- let
- val mk_list = Code_Printer.literal_list literals;
- val mk_char = Code_Printer.literal_char literals;
- val mk_string = Code_Printer.literal_string literals;
- fun pretty pr naming thm vars fxy [(t1, _), (t2, _)] =
- case Option.map (cons t1) (implode_list naming t2)
- of SOME ts => (case implode_string naming mk_char mk_string ts
- of SOME p => p
- | NONE => mk_list (map (pr vars Code_Printer.NOBR) ts))
- | NONE => default_list (Code_Printer.infix_cons literals) (pr vars) fxy t1 t2;
- in (2, pretty) end;
-
-fun pretty_char literals =
- let
- val mk_char = Code_Printer.literal_char literals;
- fun pretty _ naming thm _ _ [(t1, _), (t2, _)] =
- case decode_char naming (t1, t2)
- of SOME c => (Code_Printer.str o mk_char) c
- | NONE => Code_Printer.nerror thm "Illegal character expression";
- in (2, pretty) end;
-
-fun pretty_message literals =
- let
- val mk_char = Code_Printer.literal_char literals;
- val mk_string = Code_Printer.literal_string literals;
- fun pretty _ naming thm _ _ [(t, _)] =
- case implode_list naming t
- of SOME ts => (case implode_string naming mk_char mk_string ts
- of SOME p => p
- | NONE => Code_Printer.nerror thm "Illegal message expression")
- | NONE => Code_Printer.nerror thm "Illegal message expression";
- in (1, pretty) end;
-
-in
-
-fun add_literal_list target thy =
- let
- val pr = pretty_list (Code_Target.the_literals thy target);
- in
- thy
- |> Code_Target.add_syntax_const target @{const_name Cons} (SOME pr)
- end;
-
-fun add_literal_list_string target thy =
- let
- val pr = pretty_list_string (Code_Target.the_literals thy target);
- in
- thy
- |> Code_Target.add_syntax_const target @{const_name Cons} (SOME pr)
- end;
-
-fun add_literal_char target thy =
- let
- val pr = pretty_char (Code_Target.the_literals thy target);
- in
- thy
- |> Code_Target.add_syntax_const target @{const_name Char} (SOME pr)
- end;
-
-fun add_literal_message str target thy =
- let
- val pr = pretty_message (Code_Target.the_literals thy target);
- in
- thy
- |> Code_Target.add_syntax_const target str (SOME pr)
- end;
-
-end;
-*}
-
-setup {*
- fold (fn target => add_literal_list target) ["SML", "OCaml", "Haskell"]
-*}
-
-code_instance list :: eq
- (Haskell -)
-
-code_const "eq_class.eq \<Colon> 'a\<Colon>eq list \<Rightarrow> 'a list \<Rightarrow> bool"
- (Haskell infixl 4 "==")
+
+consts_code Cons ("(_ ::/ _)")
setup {*
let
-
-fun list_codegen thy defs dep thyname b t gr =
- let
- val ts = HOLogic.dest_list t;
- val (_, gr') = Codegen.invoke_tycodegen thy defs dep thyname false
- (fastype_of t) gr;
- val (ps, gr'') = fold_map
- (Codegen.invoke_codegen thy defs dep thyname false) ts gr'
- in SOME (Pretty.list "[" "]" ps, gr'') end handle TERM _ => NONE;
-
-fun char_codegen thy defs dep thyname b t gr =
- let
- val i = HOLogic.dest_char t;
- val (_, gr') = Codegen.invoke_tycodegen thy defs dep thyname false
- (fastype_of t) gr;
- in SOME (Codegen.str (ML_Syntax.print_string (chr i)), gr')
- end handle TERM _ => NONE;
-
+ fun list_codegen thy defs dep thyname b t gr =
+ let
+ val ts = HOLogic.dest_list t;
+ val (_, gr') = Codegen.invoke_tycodegen thy defs dep thyname false
+ (fastype_of t) gr;
+ val (ps, gr'') = fold_map
+ (Codegen.invoke_codegen thy defs dep thyname false) ts gr'
+ in SOME (Pretty.list "[" "]" ps, gr'') end handle TERM _ => NONE;
in
- Codegen.add_codegen "list_codegen" list_codegen
- #> Codegen.add_codegen "char_codegen" char_codegen
-end;
+ fold (List_Code.add_literal_list) ["SML", "OCaml", "Haskell"]
+ #> Codegen.add_codegen "list_codegen" list_codegen
+end
*}
--- a/src/HOL/Map.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Map.thy Mon May 11 17:20:52 2009 +0200
@@ -11,7 +11,7 @@
imports List
begin
-types ('a,'b) "~=>" = "'a => 'b option" (infixr 0)
+types ('a,'b) "~=>" = "'a => 'b option" (infixr "~=>" 0)
translations (type) "a ~=> b " <= (type) "a => b option"
syntax (xsymbols)
@@ -452,6 +452,9 @@
subsection {* @{term [source] dom} *}
+lemma dom_eq_empty_conv [simp]: "dom f = {} \<longleftrightarrow> f = empty"
+by(auto intro!:ext simp: dom_def)
+
lemma domI: "m a = Some b ==> a : dom m"
by(simp add:dom_def)
(* declare domI [intro]? *)
@@ -593,4 +596,19 @@
lemma map_add_le_mapI: "\<lbrakk> f \<subseteq>\<^sub>m h; g \<subseteq>\<^sub>m h; f \<subseteq>\<^sub>m f++g \<rbrakk> \<Longrightarrow> f++g \<subseteq>\<^sub>m h"
by (clarsimp simp add: map_le_def map_add_def dom_def split: option.splits)
+
+lemma dom_eq_singleton_conv: "dom f = {x} \<longleftrightarrow> (\<exists>v. f = [x \<mapsto> v])"
+proof(rule iffI)
+ assume "\<exists>v. f = [x \<mapsto> v]"
+ thus "dom f = {x}" by(auto split: split_if_asm)
+next
+ assume "dom f = {x}"
+ then obtain v where "f x = Some v" by auto
+ hence "[x \<mapsto> v] \<subseteq>\<^sub>m f" by(auto simp add: map_le_def)
+ moreover have "f \<subseteq>\<^sub>m [x \<mapsto> v]" using `dom f = {x}` `f x = Some v`
+ by(auto simp add: map_le_def)
+ ultimately have "f = [x \<mapsto> v]" by-(rule map_le_antisym)
+ thus "\<exists>v. f = [x \<mapsto> v]" by blast
+qed
+
end
--- a/src/HOL/MicroJava/Comp/CorrCompTp.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/MicroJava/Comp/CorrCompTp.thy Mon May 11 17:20:52 2009 +0200
@@ -454,7 +454,7 @@
apply (simp add: max_of_list_def)
apply (induct xs)
apply simp
-using [[fast_arith_split_limit = 0]]
+using [[linarith_split_limit = 0]]
apply simp
apply arith
done
--- a/src/HOL/NSA/HDeriv.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/NSA/HDeriv.thy Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title : Deriv.thy
- ID : $Id$
Author : Jacques D. Fleuriot
Copyright : 1998 University of Cambridge
Conversion to Isar and new proofs by Lawrence C Paulson, 2004
@@ -345,7 +344,7 @@
(*Can't get rid of x \<noteq> 0 because it isn't continuous at zero*)
lemma NSDERIV_inverse:
- fixes x :: "'a::{real_normed_field,recpower}"
+ fixes x :: "'a::{real_normed_field}"
shows "x \<noteq> 0 ==> NSDERIV (%x. inverse(x)) x :> (- (inverse x ^ Suc (Suc 0)))"
apply (simp add: nsderiv_def)
apply (rule ballI, simp, clarify)
@@ -383,7 +382,7 @@
text{*Derivative of inverse*}
lemma NSDERIV_inverse_fun:
- fixes x :: "'a::{real_normed_field,recpower}"
+ fixes x :: "'a::{real_normed_field}"
shows "[| NSDERIV f x :> d; f(x) \<noteq> 0 |]
==> NSDERIV (%x. inverse(f x)) x :> (- (d * inverse(f(x) ^ Suc (Suc 0))))"
by (simp add: NSDERIV_DERIV_iff DERIV_inverse_fun del: power_Suc)
@@ -391,7 +390,7 @@
text{*Derivative of quotient*}
lemma NSDERIV_quotient:
- fixes x :: "'a::{real_normed_field,recpower}"
+ fixes x :: "'a::{real_normed_field}"
shows "[| NSDERIV f x :> d; NSDERIV g x :> e; g(x) \<noteq> 0 |]
==> NSDERIV (%y. f(y) / (g y)) x :> (d*g(x)
- (e*f(x))) / (g(x) ^ Suc (Suc 0))"
--- a/src/HOL/NSA/HSEQ.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/NSA/HSEQ.thy Mon May 11 17:20:52 2009 +0200
@@ -110,7 +110,7 @@
done
lemma NSLIMSEQ_pow [rule_format]:
- fixes a :: "'a::{real_normed_algebra,recpower}"
+ fixes a :: "'a::{real_normed_algebra,power}"
shows "(X ----NS> a) --> ((%n. (X n) ^ m) ----NS> a ^ m)"
apply (induct "m")
apply (auto simp add: power_Suc intro: NSLIMSEQ_mult NSLIMSEQ_const)
--- a/src/HOL/NSA/HyperDef.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/NSA/HyperDef.thy Mon May 11 17:20:52 2009 +0200
@@ -417,7 +417,7 @@
declare power_hypreal_of_real_number_of [of _ "number_of w", standard, simp]
(*
lemma hrealpow_HFinite:
- fixes x :: "'a::{real_normed_algebra,recpower} star"
+ fixes x :: "'a::{real_normed_algebra,power} star"
shows "x \<in> HFinite ==> x ^ n \<in> HFinite"
apply (induct_tac "n")
apply (auto simp add: power_Suc intro: HFinite_mult)
@@ -438,71 +438,71 @@
by (simp add: hyperpow_def starfun2_star_n)
lemma hyperpow_zero [simp]:
- "\<And>n. (0::'a::{recpower,semiring_0} star) pow (n + (1::hypnat)) = 0"
+ "\<And>n. (0::'a::{power,semiring_0} star) pow (n + (1::hypnat)) = 0"
by transfer simp
lemma hyperpow_not_zero:
- "\<And>r n. r \<noteq> (0::'a::{recpower,field} star) ==> r pow n \<noteq> 0"
+ "\<And>r n. r \<noteq> (0::'a::{field} star) ==> r pow n \<noteq> 0"
by transfer (rule field_power_not_zero)
lemma hyperpow_inverse:
- "\<And>r n. r \<noteq> (0::'a::{recpower,division_by_zero,field} star)
+ "\<And>r n. r \<noteq> (0::'a::{division_by_zero,field} star)
\<Longrightarrow> inverse (r pow n) = (inverse r) pow n"
by transfer (rule power_inverse)
-
+
lemma hyperpow_hrabs:
- "\<And>r n. abs (r::'a::{recpower,ordered_idom} star) pow n = abs (r pow n)"
+ "\<And>r n. abs (r::'a::{ordered_idom} star) pow n = abs (r pow n)"
by transfer (rule power_abs [symmetric])
lemma hyperpow_add:
- "\<And>r n m. (r::'a::recpower star) pow (n + m) = (r pow n) * (r pow m)"
+ "\<And>r n m. (r::'a::monoid_mult star) pow (n + m) = (r pow n) * (r pow m)"
by transfer (rule power_add)
lemma hyperpow_one [simp]:
- "\<And>r. (r::'a::recpower star) pow (1::hypnat) = r"
+ "\<And>r. (r::'a::monoid_mult star) pow (1::hypnat) = r"
by transfer (rule power_one_right)
lemma hyperpow_two:
- "\<And>r. (r::'a::recpower star) pow ((1::hypnat) + (1::hypnat)) = r * r"
-by transfer (simp add: power_Suc)
+ "\<And>r. (r::'a::monoid_mult star) pow ((1::hypnat) + (1::hypnat)) = r * r"
+by transfer simp
lemma hyperpow_gt_zero:
- "\<And>r n. (0::'a::{recpower,ordered_semidom} star) < r \<Longrightarrow> 0 < r pow n"
+ "\<And>r n. (0::'a::{ordered_semidom} star) < r \<Longrightarrow> 0 < r pow n"
by transfer (rule zero_less_power)
lemma hyperpow_ge_zero:
- "\<And>r n. (0::'a::{recpower,ordered_semidom} star) \<le> r \<Longrightarrow> 0 \<le> r pow n"
+ "\<And>r n. (0::'a::{ordered_semidom} star) \<le> r \<Longrightarrow> 0 \<le> r pow n"
by transfer (rule zero_le_power)
lemma hyperpow_le:
- "\<And>x y n. \<lbrakk>(0::'a::{recpower,ordered_semidom} star) < x; x \<le> y\<rbrakk>
+ "\<And>x y n. \<lbrakk>(0::'a::{ordered_semidom} star) < x; x \<le> y\<rbrakk>
\<Longrightarrow> x pow n \<le> y pow n"
by transfer (rule power_mono [OF _ order_less_imp_le])
lemma hyperpow_eq_one [simp]:
- "\<And>n. 1 pow n = (1::'a::recpower star)"
+ "\<And>n. 1 pow n = (1::'a::monoid_mult star)"
by transfer (rule power_one)
lemma hrabs_hyperpow_minus_one [simp]:
- "\<And>n. abs(-1 pow n) = (1::'a::{number_ring,recpower,ordered_idom} star)"
+ "\<And>n. abs(-1 pow n) = (1::'a::{number_ring,ordered_idom} star)"
by transfer (rule abs_power_minus_one)
lemma hyperpow_mult:
- "\<And>r s n. (r * s::'a::{comm_monoid_mult,recpower} star) pow n
+ "\<And>r s n. (r * s::'a::{comm_monoid_mult} star) pow n
= (r pow n) * (s pow n)"
by transfer (rule power_mult_distrib)
lemma hyperpow_two_le [simp]:
- "(0::'a::{recpower,ordered_ring_strict} star) \<le> r pow (1 + 1)"
+ "(0::'a::{monoid_mult,ordered_ring_strict} star) \<le> r pow (1 + 1)"
by (auto simp add: hyperpow_two zero_le_mult_iff)
lemma hrabs_hyperpow_two [simp]:
"abs(x pow (1 + 1)) =
- (x::'a::{recpower,ordered_ring_strict} star) pow (1 + 1)"
+ (x::'a::{monoid_mult,ordered_ring_strict} star) pow (1 + 1)"
by (simp only: abs_of_nonneg hyperpow_two_le)
lemma hyperpow_two_hrabs [simp]:
- "abs(x::'a::{recpower,ordered_idom} star) pow (1 + 1) = x pow (1 + 1)"
+ "abs(x::'a::{ordered_idom} star) pow (1 + 1) = x pow (1 + 1)"
by (simp add: hyperpow_hrabs)
text{*The precondition could be weakened to @{term "0\<le>x"}*}
@@ -511,11 +511,11 @@
by (simp add: Ring_and_Field.mult_strict_mono order_less_imp_le)
lemma hyperpow_two_gt_one:
- "\<And>r::'a::{recpower,ordered_semidom} star. 1 < r \<Longrightarrow> 1 < r pow (1 + 1)"
+ "\<And>r::'a::{ordered_semidom} star. 1 < r \<Longrightarrow> 1 < r pow (1 + 1)"
by transfer (simp add: power_gt1 del: power_Suc)
lemma hyperpow_two_ge_one:
- "\<And>r::'a::{recpower,ordered_semidom} star. 1 \<le> r \<Longrightarrow> 1 \<le> r pow (1 + 1)"
+ "\<And>r::'a::{ordered_semidom} star. 1 \<le> r \<Longrightarrow> 1 \<le> r pow (1 + 1)"
by transfer (simp add: one_le_power del: power_Suc)
lemma two_hyperpow_ge_one [simp]: "(1::hypreal) \<le> 2 pow n"
@@ -565,7 +565,7 @@
lemma of_hypreal_hyperpow:
"\<And>x n. of_hypreal (x pow n) =
- (of_hypreal x::'a::{real_algebra_1,recpower} star) pow n"
+ (of_hypreal x::'a::{real_algebra_1} star) pow n"
by transfer (rule of_real_power)
end
--- a/src/HOL/NSA/NSA.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/NSA/NSA.thy Mon May 11 17:20:52 2009 +0200
@@ -101,7 +101,7 @@
by transfer (rule norm_mult)
lemma hnorm_hyperpow:
- "\<And>(x::'a::{real_normed_div_algebra,recpower} star) n.
+ "\<And>(x::'a::{real_normed_div_algebra} star) n.
hnorm (x pow n) = hnorm x pow n"
by transfer (rule norm_power)
@@ -304,15 +304,15 @@
unfolding star_one_def by (rule HFinite_star_of)
lemma hrealpow_HFinite:
- fixes x :: "'a::{real_normed_algebra,recpower} star"
+ fixes x :: "'a::{real_normed_algebra,monoid_mult} star"
shows "x \<in> HFinite ==> x ^ n \<in> HFinite"
-apply (induct_tac "n")
+apply (induct n)
apply (auto simp add: power_Suc intro: HFinite_mult)
done
lemma HFinite_bounded:
"[|(x::hypreal) \<in> HFinite; y \<le> x; 0 \<le> y |] ==> y \<in> HFinite"
-apply (case_tac "x \<le> 0")
+apply (cases "x \<le> 0")
apply (drule_tac y = x in order_trans)
apply (drule_tac [2] order_antisym)
apply (auto simp add: linorder_not_le)
--- a/src/HOL/NSA/NSComplex.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/NSA/NSComplex.thy Mon May 11 17:20:52 2009 +0200
@@ -383,7 +383,7 @@
by transfer (rule power_mult_distrib)
lemma hcpow_zero2 [simp]:
- "\<And>n. 0 pow (hSuc n) = (0::'a::{recpower,semiring_0} star)"
+ "\<And>n. 0 pow (hSuc n) = (0::'a::{power,semiring_0} star)"
by transfer (rule power_0_Suc)
lemma hcpow_not_zero [simp,intro]:
--- a/src/HOL/NSA/StarDef.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/NSA/StarDef.thy Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title : HOL/Hyperreal/StarDef.thy
- ID : $Id$
Author : Jacques D. Fleuriot and Brian Huffman
*)
@@ -546,16 +545,6 @@
end
-instantiation star :: (power) power
-begin
-
-definition
- star_power_def: "(op ^) \<equiv> \<lambda>x n. ( *f* (\<lambda>x. x ^ n)) x"
-
-instance ..
-
-end
-
instantiation star :: (ord) ord
begin
@@ -574,7 +563,7 @@
star_add_def star_diff_def star_minus_def
star_mult_def star_divide_def star_inverse_def
star_le_def star_less_def star_abs_def star_sgn_def
- star_div_def star_mod_def star_power_def
+ star_div_def star_mod_def
text {* Class operations preserve standard elements *}
@@ -614,15 +603,11 @@
lemma Standard_mod: "\<lbrakk>x \<in> Standard; y \<in> Standard\<rbrakk> \<Longrightarrow> x mod y \<in> Standard"
by (simp add: star_mod_def)
-lemma Standard_power: "x \<in> Standard \<Longrightarrow> x ^ n \<in> Standard"
-by (simp add: star_power_def)
-
lemmas Standard_simps [simp] =
Standard_zero Standard_one Standard_number_of
Standard_add Standard_diff Standard_minus
Standard_mult Standard_divide Standard_inverse
Standard_abs Standard_div Standard_mod
- Standard_power
text {* @{term star_of} preserves class operations *}
@@ -650,9 +635,6 @@
lemma star_of_mod: "star_of (x mod y) = star_of x mod star_of y"
by transfer (rule refl)
-lemma star_of_power: "star_of (x ^ n) = star_of x ^ n"
-by transfer (rule refl)
-
lemma star_of_abs: "star_of (abs x) = abs (star_of x)"
by transfer (rule refl)
@@ -717,8 +699,7 @@
lemmas star_of_simps [simp] =
star_of_add star_of_diff star_of_minus
star_of_mult star_of_divide star_of_inverse
- star_of_div star_of_mod
- star_of_power star_of_abs
+ star_of_div star_of_mod star_of_abs
star_of_zero star_of_one star_of_number_of
star_of_less star_of_le star_of_eq
star_of_0_less star_of_0_le star_of_0_eq
@@ -970,25 +951,33 @@
instance star :: (ordered_idom) ordered_idom ..
instance star :: (ordered_field) ordered_field ..
-subsection {* Power classes *}
+
+subsection {* Power *}
-text {*
- Proving the class axiom @{thm [source] power_Suc} for type
- @{typ "'a star"} is a little tricky, because it quantifies
- over values of type @{typ nat}. The transfer principle does
- not handle quantification over non-star types in general,
- but we can work around this by fixing an arbitrary @{typ nat}
- value, and then applying the transfer principle.
-*}
+lemma star_power_def [transfer_unfold]:
+ "(op ^) \<equiv> \<lambda>x n. ( *f* (\<lambda>x. x ^ n)) x"
+proof (rule eq_reflection, rule ext, rule ext)
+ fix n :: nat
+ show "\<And>x::'a star. x ^ n = ( *f* (\<lambda>x. x ^ n)) x"
+ proof (induct n)
+ case 0
+ have "\<And>x::'a star. ( *f* (\<lambda>x. 1)) x = 1"
+ by transfer simp
+ then show ?case by simp
+ next
+ case (Suc n)
+ have "\<And>x::'a star. x * ( *f* (\<lambda>x\<Colon>'a. x ^ n)) x = ( *f* (\<lambda>x\<Colon>'a. x * x ^ n)) x"
+ by transfer simp
+ with Suc show ?case by simp
+ qed
+qed
-instance star :: (recpower) recpower
-proof
- show "\<And>a::'a star. a ^ 0 = 1"
- by transfer (rule power_0)
-next
- fix n show "\<And>a::'a star. a ^ Suc n = a * a ^ n"
- by transfer (rule power_Suc)
-qed
+lemma Standard_power [simp]: "x \<in> Standard \<Longrightarrow> x ^ n \<in> Standard"
+ by (simp add: star_power_def)
+
+lemma star_of_power [simp]: "star_of (x ^ n) = star_of x ^ n"
+ by transfer (rule refl)
+
subsection {* Number classes *}
--- a/src/HOL/NSA/hypreal_arith.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/NSA/hypreal_arith.ML Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title: HOL/NSA/hypreal_arith.ML
- ID: $Id$
Author: Tobias Nipkow, TU Muenchen
Copyright 1999 TU Muenchen
@@ -24,7 +23,7 @@
in
-val hyprealT = Type ("StarDef.star", [HOLogic.realT]);
+val hyprealT = Type (@{type_name StarDef.star}, [HOLogic.realT]);
val fast_hypreal_arith_simproc =
Simplifier.simproc (the_context ())
@@ -40,7 +39,7 @@
lessD = lessD, (*Can't change lessD: the hypreals are dense!*)
neqE = neqE,
simpset = simpset addsimps simps}) #>
- arith_inj_const ("StarDef.star_of", HOLogic.realT --> hyprealT) #>
+ Lin_Arith.add_inj_const (@{const_name "StarDef.star_of"}, HOLogic.realT --> hyprealT) #>
Simplifier.map_ss (fn ss => ss addsimprocs [fast_hypreal_arith_simproc]);
end;
--- a/src/HOL/Nat.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Nat.thy Mon May 11 17:20:52 2009 +0200
@@ -1164,6 +1164,64 @@
end
+subsection {* Natural operation of natural numbers on functions *}
+
+text {*
+ We use the same logical constant for the power operations on
+ functions and relations, in order to share the same syntax.
+*}
+
+consts compow :: "nat \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> ('a \<Rightarrow> 'b)"
+
+abbreviation compower :: "('a \<Rightarrow> 'b) \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> 'b" (infixr "^^" 80) where
+ "f ^^ n \<equiv> compow n f"
+
+notation (latex output)
+ compower ("(_\<^bsup>_\<^esup>)" [1000] 1000)
+
+notation (HTML output)
+ compower ("(_\<^bsup>_\<^esup>)" [1000] 1000)
+
+text {* @{text "f ^^ n = f o ... o f"}, the n-fold composition of @{text f} *}
+
+overloading
+ funpow == "compow :: nat \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> ('a \<Rightarrow> 'a)"
+begin
+
+primrec funpow :: "nat \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a" where
+ "funpow 0 f = id"
+ | "funpow (Suc n) f = f o funpow n f"
+
+end
+
+text {* for code generation *}
+
+definition funpow :: "nat \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a" where
+ funpow_code_def [code post]: "funpow = compow"
+
+lemmas [code inline] = funpow_code_def [symmetric]
+
+lemma [code]:
+ "funpow 0 f = id"
+ "funpow (Suc n) f = f o funpow n f"
+ unfolding funpow_code_def by simp_all
+
+hide (open) const funpow
+
+lemma funpow_add:
+ "f ^^ (m + n) = f ^^ m \<circ> f ^^ n"
+ by (induct m) simp_all
+
+lemma funpow_swap1:
+ "f ((f ^^ n) x) = (f ^^ n) (f x)"
+proof -
+ have "f ((f ^^ n) x) = (f ^^ (n + 1)) x" by simp
+ also have "\<dots> = (f ^^ n o f ^^ 1) x" by (simp only: funpow_add)
+ also have "\<dots> = (f ^^ n) (f x)" by simp
+ finally show ?thesis .
+qed
+
+
subsection {* Embedding of the Naturals into any
@{text semiring_1}: @{term of_nat} *}
@@ -1189,7 +1247,7 @@
"of_nat_aux inc 0 i = i"
| "of_nat_aux inc (Suc n) i = of_nat_aux inc n (inc i)" -- {* tail recursive *}
-lemma of_nat_code [code, code unfold, code inline del]:
+lemma of_nat_code:
"of_nat n = of_nat_aux (\<lambda>i. i + 1) n 0"
proof (induct n)
case 0 then show ?case by simp
@@ -1201,9 +1259,11 @@
by simp
with Suc show ?case by (simp add: add_commute)
qed
-
+
end
+declare of_nat_code [code, code unfold, code inline del]
+
text{*Class for unital semirings with characteristic zero.
Includes non-ordered rings like the complex numbers.*}
@@ -1214,10 +1274,10 @@
text{*Special cases where either operand is zero*}
lemma of_nat_0_eq_iff [simp, noatp]: "0 = of_nat n \<longleftrightarrow> 0 = n"
- by (rule of_nat_eq_iff [of 0, simplified])
+ by (rule of_nat_eq_iff [of 0 n, unfolded of_nat_0])
lemma of_nat_eq_0_iff [simp, noatp]: "of_nat m = 0 \<longleftrightarrow> m = 0"
- by (rule of_nat_eq_iff [of _ 0, simplified])
+ by (rule of_nat_eq_iff [of m 0, unfolded of_nat_0])
lemma inj_of_nat: "inj of_nat"
by (simp add: inj_on_def)
--- a/src/HOL/NatBin.thy Mon May 11 09:39:53 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,975 +0,0 @@
-(* Title: HOL/NatBin.thy
- Author: Lawrence C Paulson, Cambridge University Computer Laboratory
- Copyright 1999 University of Cambridge
-*)
-
-header {* Binary arithmetic for the natural numbers *}
-
-theory NatBin
-imports IntDiv
-uses ("Tools/nat_simprocs.ML")
-begin
-
-text {*
- Arithmetic for naturals is reduced to that for the non-negative integers.
-*}
-
-instantiation nat :: number
-begin
-
-definition
- nat_number_of_def [code inline, code del]: "number_of v = nat (number_of v)"
-
-instance ..
-
-end
-
-lemma [code post]:
- "nat (number_of v) = number_of v"
- unfolding nat_number_of_def ..
-
-abbreviation (xsymbols)
- power2 :: "'a::power => 'a" ("(_\<twosuperior>)" [1000] 999) where
- "x\<twosuperior> == x^2"
-
-notation (latex output)
- power2 ("(_\<twosuperior>)" [1000] 999)
-
-notation (HTML output)
- power2 ("(_\<twosuperior>)" [1000] 999)
-
-
-subsection {* Predicate for negative binary numbers *}
-
-definition neg :: "int \<Rightarrow> bool" where
- "neg Z \<longleftrightarrow> Z < 0"
-
-lemma not_neg_int [simp]: "~ neg (of_nat n)"
-by (simp add: neg_def)
-
-lemma neg_zminus_int [simp]: "neg (- (of_nat (Suc n)))"
-by (simp add: neg_def neg_less_0_iff_less del: of_nat_Suc)
-
-lemmas neg_eq_less_0 = neg_def
-
-lemma not_neg_eq_ge_0: "(~neg x) = (0 \<le> x)"
-by (simp add: neg_def linorder_not_less)
-
-text{*To simplify inequalities when Numeral1 can get simplified to 1*}
-
-lemma not_neg_0: "~ neg 0"
-by (simp add: One_int_def neg_def)
-
-lemma not_neg_1: "~ neg 1"
-by (simp add: neg_def linorder_not_less zero_le_one)
-
-lemma neg_nat: "neg z ==> nat z = 0"
-by (simp add: neg_def order_less_imp_le)
-
-lemma not_neg_nat: "~ neg z ==> of_nat (nat z) = z"
-by (simp add: linorder_not_less neg_def)
-
-text {*
- If @{term Numeral0} is rewritten to 0 then this rule can't be applied:
- @{term Numeral0} IS @{term "number_of Pls"}
-*}
-
-lemma not_neg_number_of_Pls: "~ neg (number_of Int.Pls)"
- by (simp add: neg_def)
-
-lemma neg_number_of_Min: "neg (number_of Int.Min)"
- by (simp add: neg_def)
-
-lemma neg_number_of_Bit0:
- "neg (number_of (Int.Bit0 w)) = neg (number_of w)"
- by (simp add: neg_def)
-
-lemma neg_number_of_Bit1:
- "neg (number_of (Int.Bit1 w)) = neg (number_of w)"
- by (simp add: neg_def)
-
-lemmas neg_simps [simp] =
- not_neg_0 not_neg_1
- not_neg_number_of_Pls neg_number_of_Min
- neg_number_of_Bit0 neg_number_of_Bit1
-
-
-subsection{*Function @{term nat}: Coercion from Type @{typ int} to @{typ nat}*}
-
-declare nat_0 [simp] nat_1 [simp]
-
-lemma nat_number_of [simp]: "nat (number_of w) = number_of w"
-by (simp add: nat_number_of_def)
-
-lemma nat_numeral_0_eq_0 [simp]: "Numeral0 = (0::nat)"
-by (simp add: nat_number_of_def)
-
-lemma nat_numeral_1_eq_1 [simp]: "Numeral1 = (1::nat)"
-by (simp add: nat_1 nat_number_of_def)
-
-lemma numeral_1_eq_Suc_0: "Numeral1 = Suc 0"
-by (simp add: nat_numeral_1_eq_1)
-
-lemma numeral_2_eq_2: "2 = Suc (Suc 0)"
-apply (unfold nat_number_of_def)
-apply (rule nat_2)
-done
-
-
-subsection{*Function @{term int}: Coercion from Type @{typ nat} to @{typ int}*}
-
-lemma int_nat_number_of [simp]:
- "int (number_of v) =
- (if neg (number_of v :: int) then 0
- else (number_of v :: int))"
- unfolding nat_number_of_def number_of_is_id neg_def
- by simp
-
-
-subsubsection{*Successor *}
-
-lemma Suc_nat_eq_nat_zadd1: "(0::int) <= z ==> Suc (nat z) = nat (1 + z)"
-apply (rule sym)
-apply (simp add: nat_eq_iff int_Suc)
-done
-
-lemma Suc_nat_number_of_add:
- "Suc (number_of v + n) =
- (if neg (number_of v :: int) then 1+n else number_of (Int.succ v) + n)"
- unfolding nat_number_of_def number_of_is_id neg_def numeral_simps
- by (simp add: Suc_nat_eq_nat_zadd1 add_ac)
-
-lemma Suc_nat_number_of [simp]:
- "Suc (number_of v) =
- (if neg (number_of v :: int) then 1 else number_of (Int.succ v))"
-apply (cut_tac n = 0 in Suc_nat_number_of_add)
-apply (simp cong del: if_weak_cong)
-done
-
-
-subsubsection{*Addition *}
-
-lemma add_nat_number_of [simp]:
- "(number_of v :: nat) + number_of v' =
- (if v < Int.Pls then number_of v'
- else if v' < Int.Pls then number_of v
- else number_of (v + v'))"
- unfolding nat_number_of_def number_of_is_id numeral_simps
- by (simp add: nat_add_distrib)
-
-lemma nat_number_of_add_1 [simp]:
- "number_of v + (1::nat) =
- (if v < Int.Pls then 1 else number_of (Int.succ v))"
- unfolding nat_number_of_def number_of_is_id numeral_simps
- by (simp add: nat_add_distrib)
-
-lemma nat_1_add_number_of [simp]:
- "(1::nat) + number_of v =
- (if v < Int.Pls then 1 else number_of (Int.succ v))"
- unfolding nat_number_of_def number_of_is_id numeral_simps
- by (simp add: nat_add_distrib)
-
-lemma nat_1_add_1 [simp]: "1 + 1 = (2::nat)"
- by (rule int_int_eq [THEN iffD1]) simp
-
-
-subsubsection{*Subtraction *}
-
-lemma diff_nat_eq_if:
- "nat z - nat z' =
- (if neg z' then nat z
- else let d = z-z' in
- if neg d then 0 else nat d)"
-by (simp add: Let_def nat_diff_distrib [symmetric] neg_eq_less_0 not_neg_eq_ge_0)
-
-
-lemma diff_nat_number_of [simp]:
- "(number_of v :: nat) - number_of v' =
- (if v' < Int.Pls then number_of v
- else let d = number_of (v + uminus v') in
- if neg d then 0 else nat d)"
- unfolding nat_number_of_def number_of_is_id numeral_simps neg_def
- by auto
-
-lemma nat_number_of_diff_1 [simp]:
- "number_of v - (1::nat) =
- (if v \<le> Int.Pls then 0 else number_of (Int.pred v))"
- unfolding nat_number_of_def number_of_is_id numeral_simps
- by auto
-
-
-subsubsection{*Multiplication *}
-
-lemma mult_nat_number_of [simp]:
- "(number_of v :: nat) * number_of v' =
- (if v < Int.Pls then 0 else number_of (v * v'))"
- unfolding nat_number_of_def number_of_is_id numeral_simps
- by (simp add: nat_mult_distrib)
-
-
-subsubsection{*Quotient *}
-
-lemma div_nat_number_of [simp]:
- "(number_of v :: nat) div number_of v' =
- (if neg (number_of v :: int) then 0
- else nat (number_of v div number_of v'))"
- unfolding nat_number_of_def number_of_is_id neg_def
- by (simp add: nat_div_distrib)
-
-lemma one_div_nat_number_of [simp]:
- "Suc 0 div number_of v' = nat (1 div number_of v')"
-by (simp del: nat_numeral_1_eq_1 add: numeral_1_eq_Suc_0 [symmetric])
-
-
-subsubsection{*Remainder *}
-
-lemma mod_nat_number_of [simp]:
- "(number_of v :: nat) mod number_of v' =
- (if neg (number_of v :: int) then 0
- else if neg (number_of v' :: int) then number_of v
- else nat (number_of v mod number_of v'))"
- unfolding nat_number_of_def number_of_is_id neg_def
- by (simp add: nat_mod_distrib)
-
-lemma one_mod_nat_number_of [simp]:
- "Suc 0 mod number_of v' =
- (if neg (number_of v' :: int) then Suc 0
- else nat (1 mod number_of v'))"
-by (simp del: nat_numeral_1_eq_1 add: numeral_1_eq_Suc_0 [symmetric])
-
-
-subsubsection{* Divisibility *}
-
-lemmas dvd_eq_mod_eq_0_number_of =
- dvd_eq_mod_eq_0 [of "number_of x" "number_of y", standard]
-
-declare dvd_eq_mod_eq_0_number_of [simp]
-
-ML
-{*
-val nat_number_of_def = thm"nat_number_of_def";
-
-val nat_number_of = thm"nat_number_of";
-val nat_numeral_0_eq_0 = thm"nat_numeral_0_eq_0";
-val nat_numeral_1_eq_1 = thm"nat_numeral_1_eq_1";
-val numeral_1_eq_Suc_0 = thm"numeral_1_eq_Suc_0";
-val numeral_2_eq_2 = thm"numeral_2_eq_2";
-val nat_div_distrib = thm"nat_div_distrib";
-val nat_mod_distrib = thm"nat_mod_distrib";
-val int_nat_number_of = thm"int_nat_number_of";
-val Suc_nat_eq_nat_zadd1 = thm"Suc_nat_eq_nat_zadd1";
-val Suc_nat_number_of_add = thm"Suc_nat_number_of_add";
-val Suc_nat_number_of = thm"Suc_nat_number_of";
-val add_nat_number_of = thm"add_nat_number_of";
-val diff_nat_eq_if = thm"diff_nat_eq_if";
-val diff_nat_number_of = thm"diff_nat_number_of";
-val mult_nat_number_of = thm"mult_nat_number_of";
-val div_nat_number_of = thm"div_nat_number_of";
-val mod_nat_number_of = thm"mod_nat_number_of";
-*}
-
-
-subsection{*Comparisons*}
-
-subsubsection{*Equals (=) *}
-
-lemma eq_nat_nat_iff:
- "[| (0::int) <= z; 0 <= z' |] ==> (nat z = nat z') = (z=z')"
-by (auto elim!: nonneg_eq_int)
-
-lemma eq_nat_number_of [simp]:
- "((number_of v :: nat) = number_of v') =
- (if neg (number_of v :: int) then (number_of v' :: int) \<le> 0
- else if neg (number_of v' :: int) then (number_of v :: int) = 0
- else v = v')"
- unfolding nat_number_of_def number_of_is_id neg_def
- by auto
-
-
-subsubsection{*Less-than (<) *}
-
-lemma less_nat_number_of [simp]:
- "(number_of v :: nat) < number_of v' \<longleftrightarrow>
- (if v < v' then Int.Pls < v' else False)"
- unfolding nat_number_of_def number_of_is_id numeral_simps
- by auto
-
-
-subsubsection{*Less-than-or-equal *}
-
-lemma le_nat_number_of [simp]:
- "(number_of v :: nat) \<le> number_of v' \<longleftrightarrow>
- (if v \<le> v' then True else v \<le> Int.Pls)"
- unfolding nat_number_of_def number_of_is_id numeral_simps
- by auto
-
-(*Maps #n to n for n = 0, 1, 2*)
-lemmas numerals = nat_numeral_0_eq_0 nat_numeral_1_eq_1 numeral_2_eq_2
-
-
-subsection{*Powers with Numeric Exponents*}
-
-text{*We cannot refer to the number @{term 2} in @{text Ring_and_Field.thy}.
-We cannot prove general results about the numeral @{term "-1"}, so we have to
-use @{term "- 1"} instead.*}
-
-lemma power2_eq_square: "(a::'a::recpower)\<twosuperior> = a * a"
- by (simp add: numeral_2_eq_2 Power.power_Suc)
-
-lemma zero_power2 [simp]: "(0::'a::{semiring_1,recpower})\<twosuperior> = 0"
- by (simp add: power2_eq_square)
-
-lemma one_power2 [simp]: "(1::'a::{semiring_1,recpower})\<twosuperior> = 1"
- by (simp add: power2_eq_square)
-
-lemma power3_eq_cube: "(x::'a::recpower) ^ 3 = x * x * x"
- apply (subgoal_tac "3 = Suc (Suc (Suc 0))")
- apply (erule ssubst)
- apply (simp add: power_Suc mult_ac)
- apply (unfold nat_number_of_def)
- apply (subst nat_eq_iff)
- apply simp
-done
-
-text{*Squares of literal numerals will be evaluated.*}
-lemmas power2_eq_square_number_of =
- power2_eq_square [of "number_of w", standard]
-declare power2_eq_square_number_of [simp]
-
-
-lemma zero_le_power2[simp]: "0 \<le> (a\<twosuperior>::'a::{ordered_idom,recpower})"
- by (simp add: power2_eq_square)
-
-lemma zero_less_power2[simp]:
- "(0 < a\<twosuperior>) = (a \<noteq> (0::'a::{ordered_idom,recpower}))"
- by (force simp add: power2_eq_square zero_less_mult_iff linorder_neq_iff)
-
-lemma power2_less_0[simp]:
- fixes a :: "'a::{ordered_idom,recpower}"
- shows "~ (a\<twosuperior> < 0)"
-by (force simp add: power2_eq_square mult_less_0_iff)
-
-lemma zero_eq_power2[simp]:
- "(a\<twosuperior> = 0) = (a = (0::'a::{ordered_idom,recpower}))"
- by (force simp add: power2_eq_square mult_eq_0_iff)
-
-lemma abs_power2[simp]:
- "abs(a\<twosuperior>) = (a\<twosuperior>::'a::{ordered_idom,recpower})"
- by (simp add: power2_eq_square abs_mult abs_mult_self)
-
-lemma power2_abs[simp]:
- "(abs a)\<twosuperior> = (a\<twosuperior>::'a::{ordered_idom,recpower})"
- by (simp add: power2_eq_square abs_mult_self)
-
-lemma power2_minus[simp]:
- "(- a)\<twosuperior> = (a\<twosuperior>::'a::{comm_ring_1,recpower})"
- by (simp add: power2_eq_square)
-
-lemma power2_le_imp_le:
- fixes x y :: "'a::{ordered_semidom,recpower}"
- shows "\<lbrakk>x\<twosuperior> \<le> y\<twosuperior>; 0 \<le> y\<rbrakk> \<Longrightarrow> x \<le> y"
-unfolding numeral_2_eq_2 by (rule power_le_imp_le_base)
-
-lemma power2_less_imp_less:
- fixes x y :: "'a::{ordered_semidom,recpower}"
- shows "\<lbrakk>x\<twosuperior> < y\<twosuperior>; 0 \<le> y\<rbrakk> \<Longrightarrow> x < y"
-by (rule power_less_imp_less_base)
-
-lemma power2_eq_imp_eq:
- fixes x y :: "'a::{ordered_semidom,recpower}"
- shows "\<lbrakk>x\<twosuperior> = y\<twosuperior>; 0 \<le> x; 0 \<le> y\<rbrakk> \<Longrightarrow> x = y"
-unfolding numeral_2_eq_2 by (erule (2) power_eq_imp_eq_base, simp)
-
-lemma power_minus1_even[simp]: "(- 1) ^ (2*n) = (1::'a::{comm_ring_1,recpower})"
-proof (induct n)
- case 0 show ?case by simp
-next
- case (Suc n) then show ?case by (simp add: power_Suc power_add)
-qed
-
-lemma power_minus1_odd: "(- 1) ^ Suc(2*n) = -(1::'a::{comm_ring_1,recpower})"
- by (simp add: power_Suc)
-
-lemma power_even_eq: "(a::'a::recpower) ^ (2*n) = (a^n)^2"
-by (subst mult_commute) (simp add: power_mult)
-
-lemma power_odd_eq: "(a::int) ^ Suc(2*n) = a * (a^n)^2"
-by (simp add: power_even_eq)
-
-lemma power_minus_even [simp]:
- "(-a) ^ (2*n) = (a::'a::{comm_ring_1,recpower}) ^ (2*n)"
-by (simp add: power_minus1_even power_minus [of a])
-
-lemma zero_le_even_power'[simp]:
- "0 \<le> (a::'a::{ordered_idom,recpower}) ^ (2*n)"
-proof (induct "n")
- case 0
- show ?case by (simp add: zero_le_one)
-next
- case (Suc n)
- have "a ^ (2 * Suc n) = (a*a) * a ^ (2*n)"
- by (simp add: mult_ac power_add power2_eq_square)
- thus ?case
- by (simp add: prems zero_le_mult_iff)
-qed
-
-lemma odd_power_less_zero:
- "(a::'a::{ordered_idom,recpower}) < 0 ==> a ^ Suc(2*n) < 0"
-proof (induct "n")
- case 0
- then show ?case by simp
-next
- case (Suc n)
- have "a ^ Suc (2 * Suc n) = (a*a) * a ^ Suc(2*n)"
- by (simp add: mult_ac power_add power2_eq_square)
- thus ?case
- by (simp del: power_Suc add: prems mult_less_0_iff mult_neg_neg)
-qed
-
-lemma odd_0_le_power_imp_0_le:
- "0 \<le> a ^ Suc(2*n) ==> 0 \<le> (a::'a::{ordered_idom,recpower})"
-apply (insert odd_power_less_zero [of a n])
-apply (force simp add: linorder_not_less [symmetric])
-done
-
-text{*Simprules for comparisons where common factors can be cancelled.*}
-lemmas zero_compare_simps =
- add_strict_increasing add_strict_increasing2 add_increasing
- zero_le_mult_iff zero_le_divide_iff
- zero_less_mult_iff zero_less_divide_iff
- mult_le_0_iff divide_le_0_iff
- mult_less_0_iff divide_less_0_iff
- zero_le_power2 power2_less_0
-
-subsubsection{*Nat *}
-
-lemma Suc_pred': "0 < n ==> n = Suc(n - 1)"
-by (simp add: numerals)
-
-(*Expresses a natural number constant as the Suc of another one.
- NOT suitable for rewriting because n recurs in the condition.*)
-lemmas expand_Suc = Suc_pred' [of "number_of v", standard]
-
-subsubsection{*Arith *}
-
-lemma Suc_eq_add_numeral_1: "Suc n = n + 1"
-by (simp add: numerals)
-
-lemma Suc_eq_add_numeral_1_left: "Suc n = 1 + n"
-by (simp add: numerals)
-
-(* These two can be useful when m = number_of... *)
-
-lemma add_eq_if: "(m::nat) + n = (if m=0 then n else Suc ((m - 1) + n))"
- unfolding One_nat_def by (cases m) simp_all
-
-lemma mult_eq_if: "(m::nat) * n = (if m=0 then 0 else n + ((m - 1) * n))"
- unfolding One_nat_def by (cases m) simp_all
-
-lemma power_eq_if: "(p ^ m :: nat) = (if m=0 then 1 else p * (p ^ (m - 1)))"
- unfolding One_nat_def by (cases m) simp_all
-
-
-subsection{*Comparisons involving (0::nat) *}
-
-text{*Simplification already does @{term "n<0"}, @{term "n\<le>0"} and @{term "0\<le>n"}.*}
-
-lemma eq_number_of_0 [simp]:
- "number_of v = (0::nat) \<longleftrightarrow> v \<le> Int.Pls"
- unfolding nat_number_of_def number_of_is_id numeral_simps
- by auto
-
-lemma eq_0_number_of [simp]:
- "(0::nat) = number_of v \<longleftrightarrow> v \<le> Int.Pls"
-by (rule trans [OF eq_sym_conv eq_number_of_0])
-
-lemma less_0_number_of [simp]:
- "(0::nat) < number_of v \<longleftrightarrow> Int.Pls < v"
- unfolding nat_number_of_def number_of_is_id numeral_simps
- by simp
-
-lemma neg_imp_number_of_eq_0: "neg (number_of v :: int) ==> number_of v = (0::nat)"
-by (simp del: nat_numeral_0_eq_0 add: nat_numeral_0_eq_0 [symmetric])
-
-
-
-subsection{*Comparisons involving @{term Suc} *}
-
-lemma eq_number_of_Suc [simp]:
- "(number_of v = Suc n) =
- (let pv = number_of (Int.pred v) in
- if neg pv then False else nat pv = n)"
-apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less
- number_of_pred nat_number_of_def
- split add: split_if)
-apply (rule_tac x = "number_of v" in spec)
-apply (auto simp add: nat_eq_iff)
-done
-
-lemma Suc_eq_number_of [simp]:
- "(Suc n = number_of v) =
- (let pv = number_of (Int.pred v) in
- if neg pv then False else nat pv = n)"
-by (rule trans [OF eq_sym_conv eq_number_of_Suc])
-
-lemma less_number_of_Suc [simp]:
- "(number_of v < Suc n) =
- (let pv = number_of (Int.pred v) in
- if neg pv then True else nat pv < n)"
-apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less
- number_of_pred nat_number_of_def
- split add: split_if)
-apply (rule_tac x = "number_of v" in spec)
-apply (auto simp add: nat_less_iff)
-done
-
-lemma less_Suc_number_of [simp]:
- "(Suc n < number_of v) =
- (let pv = number_of (Int.pred v) in
- if neg pv then False else n < nat pv)"
-apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less
- number_of_pred nat_number_of_def
- split add: split_if)
-apply (rule_tac x = "number_of v" in spec)
-apply (auto simp add: zless_nat_eq_int_zless)
-done
-
-lemma le_number_of_Suc [simp]:
- "(number_of v <= Suc n) =
- (let pv = number_of (Int.pred v) in
- if neg pv then True else nat pv <= n)"
-by (simp add: Let_def less_Suc_number_of linorder_not_less [symmetric])
-
-lemma le_Suc_number_of [simp]:
- "(Suc n <= number_of v) =
- (let pv = number_of (Int.pred v) in
- if neg pv then False else n <= nat pv)"
-by (simp add: Let_def less_number_of_Suc linorder_not_less [symmetric])
-
-
-lemma eq_number_of_Pls_Min: "(Numeral0 ::int) ~= number_of Int.Min"
-by auto
-
-
-
-subsection{*Max and Min Combined with @{term Suc} *}
-
-lemma max_number_of_Suc [simp]:
- "max (Suc n) (number_of v) =
- (let pv = number_of (Int.pred v) in
- if neg pv then Suc n else Suc(max n (nat pv)))"
-apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def
- split add: split_if nat.split)
-apply (rule_tac x = "number_of v" in spec)
-apply auto
-done
-
-lemma max_Suc_number_of [simp]:
- "max (number_of v) (Suc n) =
- (let pv = number_of (Int.pred v) in
- if neg pv then Suc n else Suc(max (nat pv) n))"
-apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def
- split add: split_if nat.split)
-apply (rule_tac x = "number_of v" in spec)
-apply auto
-done
-
-lemma min_number_of_Suc [simp]:
- "min (Suc n) (number_of v) =
- (let pv = number_of (Int.pred v) in
- if neg pv then 0 else Suc(min n (nat pv)))"
-apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def
- split add: split_if nat.split)
-apply (rule_tac x = "number_of v" in spec)
-apply auto
-done
-
-lemma min_Suc_number_of [simp]:
- "min (number_of v) (Suc n) =
- (let pv = number_of (Int.pred v) in
- if neg pv then 0 else Suc(min (nat pv) n))"
-apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def
- split add: split_if nat.split)
-apply (rule_tac x = "number_of v" in spec)
-apply auto
-done
-
-subsection{*Literal arithmetic involving powers*}
-
-lemma nat_power_eq: "(0::int) <= z ==> nat (z^n) = nat z ^ n"
-apply (induct "n")
-apply (simp_all (no_asm_simp) add: nat_mult_distrib)
-done
-
-lemma power_nat_number_of:
- "(number_of v :: nat) ^ n =
- (if neg (number_of v :: int) then 0^n else nat ((number_of v :: int) ^ n))"
-by (simp only: simp_thms neg_nat not_neg_eq_ge_0 nat_number_of_def nat_power_eq
- split add: split_if cong: imp_cong)
-
-
-lemmas power_nat_number_of_number_of = power_nat_number_of [of _ "number_of w", standard]
-declare power_nat_number_of_number_of [simp]
-
-
-
-text{*For arbitrary rings*}
-
-lemma power_number_of_even:
- fixes z :: "'a::{number_ring,recpower}"
- shows "z ^ number_of (Int.Bit0 w) = (let w = z ^ (number_of w) in w * w)"
-unfolding Let_def nat_number_of_def number_of_Bit0
-apply (rule_tac x = "number_of w" in spec, clarify)
-apply (case_tac " (0::int) <= x")
-apply (auto simp add: nat_mult_distrib power_even_eq power2_eq_square)
-done
-
-lemma power_number_of_odd:
- fixes z :: "'a::{number_ring,recpower}"
- shows "z ^ number_of (Int.Bit1 w) = (if (0::int) <= number_of w
- then (let w = z ^ (number_of w) in z * w * w) else 1)"
-unfolding Let_def nat_number_of_def number_of_Bit1
-apply (rule_tac x = "number_of w" in spec, auto)
-apply (simp only: nat_add_distrib nat_mult_distrib)
-apply simp
-apply (auto simp add: nat_add_distrib nat_mult_distrib power_even_eq power2_eq_square neg_nat power_Suc)
-done
-
-lemmas zpower_number_of_even = power_number_of_even [where 'a=int]
-lemmas zpower_number_of_odd = power_number_of_odd [where 'a=int]
-
-lemmas power_number_of_even_number_of [simp] =
- power_number_of_even [of "number_of v", standard]
-
-lemmas power_number_of_odd_number_of [simp] =
- power_number_of_odd [of "number_of v", standard]
-
-
-
-ML
-{*
-val numeral_ss = @{simpset} addsimps @{thms numerals};
-
-val nat_bin_arith_setup =
- Lin_Arith.map_data
- (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset} =>
- {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms,
- inj_thms = inj_thms,
- lessD = lessD, neqE = neqE,
- simpset = simpset addsimps @{thms neg_simps} @
- [@{thm Suc_nat_number_of}, @{thm int_nat_number_of}]})
-*}
-
-declaration {* K nat_bin_arith_setup *}
-
-(* Enable arith to deal with div/mod k where k is a numeral: *)
-declare split_div[of _ _ "number_of k", standard, arith_split]
-declare split_mod[of _ _ "number_of k", standard, arith_split]
-
-lemma nat_number_of_Pls: "Numeral0 = (0::nat)"
- by (simp add: number_of_Pls nat_number_of_def)
-
-lemma nat_number_of_Min: "number_of Int.Min = (0::nat)"
- apply (simp only: number_of_Min nat_number_of_def nat_zminus_int)
- done
-
-lemma nat_number_of_Bit0:
- "number_of (Int.Bit0 w) = (let n::nat = number_of w in n + n)"
- unfolding nat_number_of_def number_of_is_id numeral_simps Let_def
- by auto
-
-lemma nat_number_of_Bit1:
- "number_of (Int.Bit1 w) =
- (if neg (number_of w :: int) then 0
- else let n = number_of w in Suc (n + n))"
- unfolding nat_number_of_def number_of_is_id numeral_simps neg_def Let_def
- by auto
-
-lemmas nat_number =
- nat_number_of_Pls nat_number_of_Min
- nat_number_of_Bit0 nat_number_of_Bit1
-
-lemma Let_Suc [simp]: "Let (Suc n) f == f (Suc n)"
- by (simp add: Let_def)
-
-lemma power_m1_even: "(-1) ^ (2*n) = (1::'a::{number_ring,recpower})"
-by (simp add: power_mult power_Suc);
-
-lemma power_m1_odd: "(-1) ^ Suc(2*n) = (-1::'a::{number_ring,recpower})"
-by (simp add: power_mult power_Suc);
-
-
-subsection{*Literal arithmetic and @{term of_nat}*}
-
-lemma of_nat_double:
- "0 \<le> x ==> of_nat (nat (2 * x)) = of_nat (nat x) + of_nat (nat x)"
-by (simp only: mult_2 nat_add_distrib of_nat_add)
-
-lemma nat_numeral_m1_eq_0: "-1 = (0::nat)"
-by (simp only: nat_number_of_def)
-
-lemma of_nat_number_of_lemma:
- "of_nat (number_of v :: nat) =
- (if 0 \<le> (number_of v :: int)
- then (number_of v :: 'a :: number_ring)
- else 0)"
-by (simp add: int_number_of_def nat_number_of_def number_of_eq of_nat_nat);
-
-lemma of_nat_number_of_eq [simp]:
- "of_nat (number_of v :: nat) =
- (if neg (number_of v :: int) then 0
- else (number_of v :: 'a :: number_ring))"
-by (simp only: of_nat_number_of_lemma neg_def, simp)
-
-
-subsection {*Lemmas for the Combination and Cancellation Simprocs*}
-
-lemma nat_number_of_add_left:
- "number_of v + (number_of v' + (k::nat)) =
- (if neg (number_of v :: int) then number_of v' + k
- else if neg (number_of v' :: int) then number_of v + k
- else number_of (v + v') + k)"
- unfolding nat_number_of_def number_of_is_id neg_def
- by auto
-
-lemma nat_number_of_mult_left:
- "number_of v * (number_of v' * (k::nat)) =
- (if v < Int.Pls then 0
- else number_of (v * v') * k)"
-by simp
-
-
-subsubsection{*For @{text combine_numerals}*}
-
-lemma left_add_mult_distrib: "i*u + (j*u + k) = (i+j)*u + (k::nat)"
-by (simp add: add_mult_distrib)
-
-
-subsubsection{*For @{text cancel_numerals}*}
-
-lemma nat_diff_add_eq1:
- "j <= (i::nat) ==> ((i*u + m) - (j*u + n)) = (((i-j)*u + m) - n)"
-by (simp split add: nat_diff_split add: add_mult_distrib)
-
-lemma nat_diff_add_eq2:
- "i <= (j::nat) ==> ((i*u + m) - (j*u + n)) = (m - ((j-i)*u + n))"
-by (simp split add: nat_diff_split add: add_mult_distrib)
-
-lemma nat_eq_add_iff1:
- "j <= (i::nat) ==> (i*u + m = j*u + n) = ((i-j)*u + m = n)"
-by (auto split add: nat_diff_split simp add: add_mult_distrib)
-
-lemma nat_eq_add_iff2:
- "i <= (j::nat) ==> (i*u + m = j*u + n) = (m = (j-i)*u + n)"
-by (auto split add: nat_diff_split simp add: add_mult_distrib)
-
-lemma nat_less_add_iff1:
- "j <= (i::nat) ==> (i*u + m < j*u + n) = ((i-j)*u + m < n)"
-by (auto split add: nat_diff_split simp add: add_mult_distrib)
-
-lemma nat_less_add_iff2:
- "i <= (j::nat) ==> (i*u + m < j*u + n) = (m < (j-i)*u + n)"
-by (auto split add: nat_diff_split simp add: add_mult_distrib)
-
-lemma nat_le_add_iff1:
- "j <= (i::nat) ==> (i*u + m <= j*u + n) = ((i-j)*u + m <= n)"
-by (auto split add: nat_diff_split simp add: add_mult_distrib)
-
-lemma nat_le_add_iff2:
- "i <= (j::nat) ==> (i*u + m <= j*u + n) = (m <= (j-i)*u + n)"
-by (auto split add: nat_diff_split simp add: add_mult_distrib)
-
-
-subsubsection{*For @{text cancel_numeral_factors} *}
-
-lemma nat_mult_le_cancel1: "(0::nat) < k ==> (k*m <= k*n) = (m<=n)"
-by auto
-
-lemma nat_mult_less_cancel1: "(0::nat) < k ==> (k*m < k*n) = (m<n)"
-by auto
-
-lemma nat_mult_eq_cancel1: "(0::nat) < k ==> (k*m = k*n) = (m=n)"
-by auto
-
-lemma nat_mult_div_cancel1: "(0::nat) < k ==> (k*m) div (k*n) = (m div n)"
-by auto
-
-lemma nat_mult_dvd_cancel_disj[simp]:
- "(k*m) dvd (k*n) = (k=0 | m dvd (n::nat))"
-by(auto simp: dvd_eq_mod_eq_0 mod_mult_distrib2[symmetric])
-
-lemma nat_mult_dvd_cancel1: "0 < k \<Longrightarrow> (k*m) dvd (k*n::nat) = (m dvd n)"
-by(auto)
-
-
-subsubsection{*For @{text cancel_factor} *}
-
-lemma nat_mult_le_cancel_disj: "(k*m <= k*n) = ((0::nat) < k --> m<=n)"
-by auto
-
-lemma nat_mult_less_cancel_disj: "(k*m < k*n) = ((0::nat) < k & m<n)"
-by auto
-
-lemma nat_mult_eq_cancel_disj: "(k*m = k*n) = (k = (0::nat) | m=n)"
-by auto
-
-lemma nat_mult_div_cancel_disj[simp]:
- "(k*m) div (k*n) = (if k = (0::nat) then 0 else m div n)"
-by (simp add: nat_mult_div_cancel1)
-
-
-subsection {* Simprocs for the Naturals *}
-
-use "Tools/nat_simprocs.ML"
-declaration {* K nat_simprocs_setup *}
-
-subsubsection{*For simplifying @{term "Suc m - K"} and @{term "K - Suc m"}*}
-
-text{*Where K above is a literal*}
-
-lemma Suc_diff_eq_diff_pred: "Numeral0 < n ==> Suc m - n = m - (n - Numeral1)"
-by (simp add: numeral_0_eq_0 numeral_1_eq_1 split add: nat_diff_split)
-
-text {*Now just instantiating @{text n} to @{text "number_of v"} does
- the right simplification, but with some redundant inequality
- tests.*}
-lemma neg_number_of_pred_iff_0:
- "neg (number_of (Int.pred v)::int) = (number_of v = (0::nat))"
-apply (subgoal_tac "neg (number_of (Int.pred v)) = (number_of v < Suc 0) ")
-apply (simp only: less_Suc_eq_le le_0_eq)
-apply (subst less_number_of_Suc, simp)
-done
-
-text{*No longer required as a simprule because of the @{text inverse_fold}
- simproc*}
-lemma Suc_diff_number_of:
- "Int.Pls < v ==>
- Suc m - (number_of v) = m - (number_of (Int.pred v))"
-apply (subst Suc_diff_eq_diff_pred)
-apply simp
-apply (simp del: nat_numeral_1_eq_1)
-apply (auto simp only: diff_nat_number_of less_0_number_of [symmetric]
- neg_number_of_pred_iff_0)
-done
-
-lemma diff_Suc_eq_diff_pred: "m - Suc n = (m - 1) - n"
-by (simp add: numerals split add: nat_diff_split)
-
-
-subsubsection{*For @{term nat_case} and @{term nat_rec}*}
-
-lemma nat_case_number_of [simp]:
- "nat_case a f (number_of v) =
- (let pv = number_of (Int.pred v) in
- if neg pv then a else f (nat pv))"
-by (simp split add: nat.split add: Let_def neg_number_of_pred_iff_0)
-
-lemma nat_case_add_eq_if [simp]:
- "nat_case a f ((number_of v) + n) =
- (let pv = number_of (Int.pred v) in
- if neg pv then nat_case a f n else f (nat pv + n))"
-apply (subst add_eq_if)
-apply (simp split add: nat.split
- del: nat_numeral_1_eq_1
- add: nat_numeral_1_eq_1 [symmetric]
- numeral_1_eq_Suc_0 [symmetric]
- neg_number_of_pred_iff_0)
-done
-
-lemma nat_rec_number_of [simp]:
- "nat_rec a f (number_of v) =
- (let pv = number_of (Int.pred v) in
- if neg pv then a else f (nat pv) (nat_rec a f (nat pv)))"
-apply (case_tac " (number_of v) ::nat")
-apply (simp_all (no_asm_simp) add: Let_def neg_number_of_pred_iff_0)
-apply (simp split add: split_if_asm)
-done
-
-lemma nat_rec_add_eq_if [simp]:
- "nat_rec a f (number_of v + n) =
- (let pv = number_of (Int.pred v) in
- if neg pv then nat_rec a f n
- else f (nat pv + n) (nat_rec a f (nat pv + n)))"
-apply (subst add_eq_if)
-apply (simp split add: nat.split
- del: nat_numeral_1_eq_1
- add: nat_numeral_1_eq_1 [symmetric]
- numeral_1_eq_Suc_0 [symmetric]
- neg_number_of_pred_iff_0)
-done
-
-
-subsubsection{*Various Other Lemmas*}
-
-text {*Evens and Odds, for Mutilated Chess Board*}
-
-text{*Lemmas for specialist use, NOT as default simprules*}
-lemma nat_mult_2: "2 * z = (z+z::nat)"
-proof -
- have "2*z = (1 + 1)*z" by simp
- also have "... = z+z" by (simp add: left_distrib)
- finally show ?thesis .
-qed
-
-lemma nat_mult_2_right: "z * 2 = (z+z::nat)"
-by (subst mult_commute, rule nat_mult_2)
-
-text{*Case analysis on @{term "n<2"}*}
-lemma less_2_cases: "(n::nat) < 2 ==> n = 0 | n = Suc 0"
-by arith
-
-lemma div2_Suc_Suc [simp]: "Suc(Suc m) div 2 = Suc (m div 2)"
-by arith
-
-lemma add_self_div_2 [simp]: "(m + m) div 2 = (m::nat)"
-by (simp add: nat_mult_2 [symmetric])
-
-lemma mod2_Suc_Suc [simp]: "Suc(Suc(m)) mod 2 = m mod 2"
-apply (subgoal_tac "m mod 2 < 2")
-apply (erule less_2_cases [THEN disjE])
-apply (simp_all (no_asm_simp) add: Let_def mod_Suc nat_1)
-done
-
-lemma mod2_gr_0 [simp]: "!!m::nat. (0 < m mod 2) = (m mod 2 = 1)"
-apply (subgoal_tac "m mod 2 < 2")
-apply (force simp del: mod_less_divisor, simp)
-done
-
-text{*Removal of Small Numerals: 0, 1 and (in additive positions) 2*}
-
-lemma add_2_eq_Suc [simp]: "2 + n = Suc (Suc n)"
-by simp
-
-lemma add_2_eq_Suc' [simp]: "n + 2 = Suc (Suc n)"
-by simp
-
-text{*Can be used to eliminate long strings of Sucs, but not by default*}
-lemma Suc3_eq_add_3: "Suc (Suc (Suc n)) = 3 + n"
-by simp
-
-
-text{*These lemmas collapse some needless occurrences of Suc:
- at least three Sucs, since two and fewer are rewritten back to Suc again!
- We already have some rules to simplify operands smaller than 3.*}
-
-lemma div_Suc_eq_div_add3 [simp]: "m div (Suc (Suc (Suc n))) = m div (3+n)"
-by (simp add: Suc3_eq_add_3)
-
-lemma mod_Suc_eq_mod_add3 [simp]: "m mod (Suc (Suc (Suc n))) = m mod (3+n)"
-by (simp add: Suc3_eq_add_3)
-
-lemma Suc_div_eq_add3_div: "(Suc (Suc (Suc m))) div n = (3+m) div n"
-by (simp add: Suc3_eq_add_3)
-
-lemma Suc_mod_eq_add3_mod: "(Suc (Suc (Suc m))) mod n = (3+m) mod n"
-by (simp add: Suc3_eq_add_3)
-
-lemmas Suc_div_eq_add3_div_number_of =
- Suc_div_eq_add3_div [of _ "number_of v", standard]
-declare Suc_div_eq_add3_div_number_of [simp]
-
-lemmas Suc_mod_eq_add3_mod_number_of =
- Suc_mod_eq_add3_mod [of _ "number_of v", standard]
-declare Suc_mod_eq_add3_mod_number_of [simp]
-
-end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Nat_Numeral.thy Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,1059 @@
+(* Title: HOL/Nat_Numeral.thy
+ Author: Lawrence C Paulson, Cambridge University Computer Laboratory
+ Copyright 1999 University of Cambridge
+*)
+
+header {* Binary numerals for the natural numbers *}
+
+theory Nat_Numeral
+imports IntDiv
+uses ("Tools/nat_numeral_simprocs.ML")
+begin
+
+subsection {* Numerals for natural numbers *}
+
+text {*
+ Arithmetic for naturals is reduced to that for the non-negative integers.
+*}
+
+instantiation nat :: number
+begin
+
+definition
+ nat_number_of_def [code inline, code del]: "number_of v = nat (number_of v)"
+
+instance ..
+
+end
+
+lemma [code post]:
+ "nat (number_of v) = number_of v"
+ unfolding nat_number_of_def ..
+
+
+subsection {* Special case: squares and cubes *}
+
+lemma numeral_2_eq_2: "2 = Suc (Suc 0)"
+ by (simp add: nat_number_of_def)
+
+lemma numeral_3_eq_3: "3 = Suc (Suc (Suc 0))"
+ by (simp add: nat_number_of_def)
+
+context power
+begin
+
+abbreviation (xsymbols)
+ power2 :: "'a \<Rightarrow> 'a" ("(_\<twosuperior>)" [1000] 999) where
+ "x\<twosuperior> \<equiv> x ^ 2"
+
+notation (latex output)
+ power2 ("(_\<twosuperior>)" [1000] 999)
+
+notation (HTML output)
+ power2 ("(_\<twosuperior>)" [1000] 999)
+
+end
+
+context monoid_mult
+begin
+
+lemma power2_eq_square: "a\<twosuperior> = a * a"
+ by (simp add: numeral_2_eq_2)
+
+lemma power3_eq_cube: "a ^ 3 = a * a * a"
+ by (simp add: numeral_3_eq_3 mult_assoc)
+
+lemma power_even_eq:
+ "a ^ (2*n) = (a ^ n) ^ 2"
+ by (subst OrderedGroup.mult_commute) (simp add: power_mult)
+
+lemma power_odd_eq:
+ "a ^ Suc (2*n) = a * (a ^ n) ^ 2"
+ by (simp add: power_even_eq)
+
+end
+
+context semiring_1
+begin
+
+lemma zero_power2 [simp]: "0\<twosuperior> = 0"
+ by (simp add: power2_eq_square)
+
+lemma one_power2 [simp]: "1\<twosuperior> = 1"
+ by (simp add: power2_eq_square)
+
+end
+
+context comm_ring_1
+begin
+
+lemma power2_minus [simp]:
+ "(- a)\<twosuperior> = a\<twosuperior>"
+ by (simp add: power2_eq_square)
+
+text{*
+ We cannot prove general results about the numeral @{term "-1"},
+ so we have to use @{term "- 1"} instead.
+*}
+
+lemma power_minus1_even [simp]:
+ "(- 1) ^ (2*n) = 1"
+proof (induct n)
+ case 0 show ?case by simp
+next
+ case (Suc n) then show ?case by (simp add: power_add)
+qed
+
+lemma power_minus1_odd:
+ "(- 1) ^ Suc (2*n) = - 1"
+ by simp
+
+lemma power_minus_even [simp]:
+ "(-a) ^ (2*n) = a ^ (2*n)"
+ by (simp add: power_minus [of a])
+
+end
+
+context ordered_ring_strict
+begin
+
+lemma sum_squares_ge_zero:
+ "0 \<le> x * x + y * y"
+ by (intro add_nonneg_nonneg zero_le_square)
+
+lemma not_sum_squares_lt_zero:
+ "\<not> x * x + y * y < 0"
+ by (simp add: not_less sum_squares_ge_zero)
+
+lemma sum_squares_eq_zero_iff:
+ "x * x + y * y = 0 \<longleftrightarrow> x = 0 \<and> y = 0"
+ by (simp add: add_nonneg_eq_0_iff)
+
+lemma sum_squares_le_zero_iff:
+ "x * x + y * y \<le> 0 \<longleftrightarrow> x = 0 \<and> y = 0"
+ by (simp add: le_less not_sum_squares_lt_zero sum_squares_eq_zero_iff)
+
+lemma sum_squares_gt_zero_iff:
+ "0 < x * x + y * y \<longleftrightarrow> x \<noteq> 0 \<or> y \<noteq> 0"
+proof -
+ have "x * x + y * y \<noteq> 0 \<longleftrightarrow> x \<noteq> 0 \<or> y \<noteq> 0"
+ by (simp add: sum_squares_eq_zero_iff)
+ then have "0 \<noteq> x * x + y * y \<longleftrightarrow> x \<noteq> 0 \<or> y \<noteq> 0"
+ by auto
+ then show ?thesis
+ by (simp add: less_le sum_squares_ge_zero)
+qed
+
+end
+
+context ordered_semidom
+begin
+
+lemma power2_le_imp_le:
+ "x\<twosuperior> \<le> y\<twosuperior> \<Longrightarrow> 0 \<le> y \<Longrightarrow> x \<le> y"
+ unfolding numeral_2_eq_2 by (rule power_le_imp_le_base)
+
+lemma power2_less_imp_less:
+ "x\<twosuperior> < y\<twosuperior> \<Longrightarrow> 0 \<le> y \<Longrightarrow> x < y"
+ by (rule power_less_imp_less_base)
+
+lemma power2_eq_imp_eq:
+ "x\<twosuperior> = y\<twosuperior> \<Longrightarrow> 0 \<le> x \<Longrightarrow> 0 \<le> y \<Longrightarrow> x = y"
+ unfolding numeral_2_eq_2 by (erule (2) power_eq_imp_eq_base) simp
+
+end
+
+context ordered_idom
+begin
+
+lemma zero_eq_power2 [simp]:
+ "a\<twosuperior> = 0 \<longleftrightarrow> a = 0"
+ by (force simp add: power2_eq_square)
+
+lemma zero_le_power2 [simp]:
+ "0 \<le> a\<twosuperior>"
+ by (simp add: power2_eq_square)
+
+lemma zero_less_power2 [simp]:
+ "0 < a\<twosuperior> \<longleftrightarrow> a \<noteq> 0"
+ by (force simp add: power2_eq_square zero_less_mult_iff linorder_neq_iff)
+
+lemma power2_less_0 [simp]:
+ "\<not> a\<twosuperior> < 0"
+ by (force simp add: power2_eq_square mult_less_0_iff)
+
+lemma abs_power2 [simp]:
+ "abs (a\<twosuperior>) = a\<twosuperior>"
+ by (simp add: power2_eq_square abs_mult abs_mult_self)
+
+lemma power2_abs [simp]:
+ "(abs a)\<twosuperior> = a\<twosuperior>"
+ by (simp add: power2_eq_square abs_mult_self)
+
+lemma odd_power_less_zero:
+ "a < 0 \<Longrightarrow> a ^ Suc (2*n) < 0"
+proof (induct n)
+ case 0
+ then show ?case by simp
+next
+ case (Suc n)
+ have "a ^ Suc (2 * Suc n) = (a*a) * a ^ Suc(2*n)"
+ by (simp add: mult_ac power_add power2_eq_square)
+ thus ?case
+ by (simp del: power_Suc add: Suc mult_less_0_iff mult_neg_neg)
+qed
+
+lemma odd_0_le_power_imp_0_le:
+ "0 \<le> a ^ Suc (2*n) \<Longrightarrow> 0 \<le> a"
+ using odd_power_less_zero [of a n]
+ by (force simp add: linorder_not_less [symmetric])
+
+lemma zero_le_even_power'[simp]:
+ "0 \<le> a ^ (2*n)"
+proof (induct n)
+ case 0
+ show ?case by (simp add: zero_le_one)
+next
+ case (Suc n)
+ have "a ^ (2 * Suc n) = (a*a) * a ^ (2*n)"
+ by (simp add: mult_ac power_add power2_eq_square)
+ thus ?case
+ by (simp add: Suc zero_le_mult_iff)
+qed
+
+lemma sum_power2_ge_zero:
+ "0 \<le> x\<twosuperior> + y\<twosuperior>"
+ unfolding power2_eq_square by (rule sum_squares_ge_zero)
+
+lemma not_sum_power2_lt_zero:
+ "\<not> x\<twosuperior> + y\<twosuperior> < 0"
+ unfolding power2_eq_square by (rule not_sum_squares_lt_zero)
+
+lemma sum_power2_eq_zero_iff:
+ "x\<twosuperior> + y\<twosuperior> = 0 \<longleftrightarrow> x = 0 \<and> y = 0"
+ unfolding power2_eq_square by (rule sum_squares_eq_zero_iff)
+
+lemma sum_power2_le_zero_iff:
+ "x\<twosuperior> + y\<twosuperior> \<le> 0 \<longleftrightarrow> x = 0 \<and> y = 0"
+ unfolding power2_eq_square by (rule sum_squares_le_zero_iff)
+
+lemma sum_power2_gt_zero_iff:
+ "0 < x\<twosuperior> + y\<twosuperior> \<longleftrightarrow> x \<noteq> 0 \<or> y \<noteq> 0"
+ unfolding power2_eq_square by (rule sum_squares_gt_zero_iff)
+
+end
+
+lemma power2_sum:
+ fixes x y :: "'a::number_ring"
+ shows "(x + y)\<twosuperior> = x\<twosuperior> + y\<twosuperior> + 2 * x * y"
+ by (simp add: ring_distribs power2_eq_square)
+
+lemma power2_diff:
+ fixes x y :: "'a::number_ring"
+ shows "(x - y)\<twosuperior> = x\<twosuperior> + y\<twosuperior> - 2 * x * y"
+ by (simp add: ring_distribs power2_eq_square)
+
+
+subsection {* Predicate for negative binary numbers *}
+
+definition neg :: "int \<Rightarrow> bool" where
+ "neg Z \<longleftrightarrow> Z < 0"
+
+lemma not_neg_int [simp]: "~ neg (of_nat n)"
+by (simp add: neg_def)
+
+lemma neg_zminus_int [simp]: "neg (- (of_nat (Suc n)))"
+by (simp add: neg_def neg_less_0_iff_less del: of_nat_Suc)
+
+lemmas neg_eq_less_0 = neg_def
+
+lemma not_neg_eq_ge_0: "(~neg x) = (0 \<le> x)"
+by (simp add: neg_def linorder_not_less)
+
+text{*To simplify inequalities when Numeral1 can get simplified to 1*}
+
+lemma not_neg_0: "~ neg 0"
+by (simp add: One_int_def neg_def)
+
+lemma not_neg_1: "~ neg 1"
+by (simp add: neg_def linorder_not_less zero_le_one)
+
+lemma neg_nat: "neg z ==> nat z = 0"
+by (simp add: neg_def order_less_imp_le)
+
+lemma not_neg_nat: "~ neg z ==> of_nat (nat z) = z"
+by (simp add: linorder_not_less neg_def)
+
+text {*
+ If @{term Numeral0} is rewritten to 0 then this rule can't be applied:
+ @{term Numeral0} IS @{term "number_of Pls"}
+*}
+
+lemma not_neg_number_of_Pls: "~ neg (number_of Int.Pls)"
+ by (simp add: neg_def)
+
+lemma neg_number_of_Min: "neg (number_of Int.Min)"
+ by (simp add: neg_def)
+
+lemma neg_number_of_Bit0:
+ "neg (number_of (Int.Bit0 w)) = neg (number_of w)"
+ by (simp add: neg_def)
+
+lemma neg_number_of_Bit1:
+ "neg (number_of (Int.Bit1 w)) = neg (number_of w)"
+ by (simp add: neg_def)
+
+lemmas neg_simps [simp] =
+ not_neg_0 not_neg_1
+ not_neg_number_of_Pls neg_number_of_Min
+ neg_number_of_Bit0 neg_number_of_Bit1
+
+
+subsection{*Function @{term nat}: Coercion from Type @{typ int} to @{typ nat}*}
+
+declare nat_0 [simp] nat_1 [simp]
+
+lemma nat_number_of [simp]: "nat (number_of w) = number_of w"
+by (simp add: nat_number_of_def)
+
+lemma nat_numeral_0_eq_0 [simp]: "Numeral0 = (0::nat)"
+by (simp add: nat_number_of_def)
+
+lemma nat_numeral_1_eq_1 [simp]: "Numeral1 = (1::nat)"
+by (simp add: nat_1 nat_number_of_def)
+
+lemma numeral_1_eq_Suc_0: "Numeral1 = Suc 0"
+by (simp add: nat_numeral_1_eq_1)
+
+
+subsection{*Function @{term int}: Coercion from Type @{typ nat} to @{typ int}*}
+
+lemma int_nat_number_of [simp]:
+ "int (number_of v) =
+ (if neg (number_of v :: int) then 0
+ else (number_of v :: int))"
+ unfolding nat_number_of_def number_of_is_id neg_def
+ by simp
+
+
+subsubsection{*Successor *}
+
+lemma Suc_nat_eq_nat_zadd1: "(0::int) <= z ==> Suc (nat z) = nat (1 + z)"
+apply (rule sym)
+apply (simp add: nat_eq_iff int_Suc)
+done
+
+lemma Suc_nat_number_of_add:
+ "Suc (number_of v + n) =
+ (if neg (number_of v :: int) then 1+n else number_of (Int.succ v) + n)"
+ unfolding nat_number_of_def number_of_is_id neg_def numeral_simps
+ by (simp add: Suc_nat_eq_nat_zadd1 add_ac)
+
+lemma Suc_nat_number_of [simp]:
+ "Suc (number_of v) =
+ (if neg (number_of v :: int) then 1 else number_of (Int.succ v))"
+apply (cut_tac n = 0 in Suc_nat_number_of_add)
+apply (simp cong del: if_weak_cong)
+done
+
+
+subsubsection{*Addition *}
+
+lemma add_nat_number_of [simp]:
+ "(number_of v :: nat) + number_of v' =
+ (if v < Int.Pls then number_of v'
+ else if v' < Int.Pls then number_of v
+ else number_of (v + v'))"
+ unfolding nat_number_of_def number_of_is_id numeral_simps
+ by (simp add: nat_add_distrib)
+
+lemma nat_number_of_add_1 [simp]:
+ "number_of v + (1::nat) =
+ (if v < Int.Pls then 1 else number_of (Int.succ v))"
+ unfolding nat_number_of_def number_of_is_id numeral_simps
+ by (simp add: nat_add_distrib)
+
+lemma nat_1_add_number_of [simp]:
+ "(1::nat) + number_of v =
+ (if v < Int.Pls then 1 else number_of (Int.succ v))"
+ unfolding nat_number_of_def number_of_is_id numeral_simps
+ by (simp add: nat_add_distrib)
+
+lemma nat_1_add_1 [simp]: "1 + 1 = (2::nat)"
+ by (rule int_int_eq [THEN iffD1]) simp
+
+
+subsubsection{*Subtraction *}
+
+lemma diff_nat_eq_if:
+ "nat z - nat z' =
+ (if neg z' then nat z
+ else let d = z-z' in
+ if neg d then 0 else nat d)"
+by (simp add: Let_def nat_diff_distrib [symmetric] neg_eq_less_0 not_neg_eq_ge_0)
+
+
+lemma diff_nat_number_of [simp]:
+ "(number_of v :: nat) - number_of v' =
+ (if v' < Int.Pls then number_of v
+ else let d = number_of (v + uminus v') in
+ if neg d then 0 else nat d)"
+ unfolding nat_number_of_def number_of_is_id numeral_simps neg_def
+ by auto
+
+lemma nat_number_of_diff_1 [simp]:
+ "number_of v - (1::nat) =
+ (if v \<le> Int.Pls then 0 else number_of (Int.pred v))"
+ unfolding nat_number_of_def number_of_is_id numeral_simps
+ by auto
+
+
+subsubsection{*Multiplication *}
+
+lemma mult_nat_number_of [simp]:
+ "(number_of v :: nat) * number_of v' =
+ (if v < Int.Pls then 0 else number_of (v * v'))"
+ unfolding nat_number_of_def number_of_is_id numeral_simps
+ by (simp add: nat_mult_distrib)
+
+
+subsubsection{*Quotient *}
+
+lemma div_nat_number_of [simp]:
+ "(number_of v :: nat) div number_of v' =
+ (if neg (number_of v :: int) then 0
+ else nat (number_of v div number_of v'))"
+ unfolding nat_number_of_def number_of_is_id neg_def
+ by (simp add: nat_div_distrib)
+
+lemma one_div_nat_number_of [simp]:
+ "Suc 0 div number_of v' = nat (1 div number_of v')"
+by (simp del: nat_numeral_1_eq_1 add: numeral_1_eq_Suc_0 [symmetric])
+
+
+subsubsection{*Remainder *}
+
+lemma mod_nat_number_of [simp]:
+ "(number_of v :: nat) mod number_of v' =
+ (if neg (number_of v :: int) then 0
+ else if neg (number_of v' :: int) then number_of v
+ else nat (number_of v mod number_of v'))"
+ unfolding nat_number_of_def number_of_is_id neg_def
+ by (simp add: nat_mod_distrib)
+
+lemma one_mod_nat_number_of [simp]:
+ "Suc 0 mod number_of v' =
+ (if neg (number_of v' :: int) then Suc 0
+ else nat (1 mod number_of v'))"
+by (simp del: nat_numeral_1_eq_1 add: numeral_1_eq_Suc_0 [symmetric])
+
+
+subsubsection{* Divisibility *}
+
+lemmas dvd_eq_mod_eq_0_number_of =
+ dvd_eq_mod_eq_0 [of "number_of x" "number_of y", standard]
+
+declare dvd_eq_mod_eq_0_number_of [simp]
+
+
+subsection{*Comparisons*}
+
+subsubsection{*Equals (=) *}
+
+lemma eq_nat_nat_iff:
+ "[| (0::int) <= z; 0 <= z' |] ==> (nat z = nat z') = (z=z')"
+by (auto elim!: nonneg_eq_int)
+
+lemma eq_nat_number_of [simp]:
+ "((number_of v :: nat) = number_of v') =
+ (if neg (number_of v :: int) then (number_of v' :: int) \<le> 0
+ else if neg (number_of v' :: int) then (number_of v :: int) = 0
+ else v = v')"
+ unfolding nat_number_of_def number_of_is_id neg_def
+ by auto
+
+
+subsubsection{*Less-than (<) *}
+
+lemma less_nat_number_of [simp]:
+ "(number_of v :: nat) < number_of v' \<longleftrightarrow>
+ (if v < v' then Int.Pls < v' else False)"
+ unfolding nat_number_of_def number_of_is_id numeral_simps
+ by auto
+
+
+subsubsection{*Less-than-or-equal *}
+
+lemma le_nat_number_of [simp]:
+ "(number_of v :: nat) \<le> number_of v' \<longleftrightarrow>
+ (if v \<le> v' then True else v \<le> Int.Pls)"
+ unfolding nat_number_of_def number_of_is_id numeral_simps
+ by auto
+
+(*Maps #n to n for n = 0, 1, 2*)
+lemmas numerals = nat_numeral_0_eq_0 nat_numeral_1_eq_1 numeral_2_eq_2
+
+
+subsection{*Powers with Numeric Exponents*}
+
+text{*Squares of literal numerals will be evaluated.*}
+lemmas power2_eq_square_number_of [simp] =
+ power2_eq_square [of "number_of w", standard]
+
+
+text{*Simprules for comparisons where common factors can be cancelled.*}
+lemmas zero_compare_simps =
+ add_strict_increasing add_strict_increasing2 add_increasing
+ zero_le_mult_iff zero_le_divide_iff
+ zero_less_mult_iff zero_less_divide_iff
+ mult_le_0_iff divide_le_0_iff
+ mult_less_0_iff divide_less_0_iff
+ zero_le_power2 power2_less_0
+
+subsubsection{*Nat *}
+
+lemma Suc_pred': "0 < n ==> n = Suc(n - 1)"
+by (simp add: numerals)
+
+(*Expresses a natural number constant as the Suc of another one.
+ NOT suitable for rewriting because n recurs in the condition.*)
+lemmas expand_Suc = Suc_pred' [of "number_of v", standard]
+
+subsubsection{*Arith *}
+
+lemma Suc_eq_add_numeral_1: "Suc n = n + 1"
+by (simp add: numerals)
+
+lemma Suc_eq_add_numeral_1_left: "Suc n = 1 + n"
+by (simp add: numerals)
+
+(* These two can be useful when m = number_of... *)
+
+lemma add_eq_if: "(m::nat) + n = (if m=0 then n else Suc ((m - 1) + n))"
+ unfolding One_nat_def by (cases m) simp_all
+
+lemma mult_eq_if: "(m::nat) * n = (if m=0 then 0 else n + ((m - 1) * n))"
+ unfolding One_nat_def by (cases m) simp_all
+
+lemma power_eq_if: "(p ^ m :: nat) = (if m=0 then 1 else p * (p ^ (m - 1)))"
+ unfolding One_nat_def by (cases m) simp_all
+
+
+subsection{*Comparisons involving (0::nat) *}
+
+text{*Simplification already does @{term "n<0"}, @{term "n\<le>0"} and @{term "0\<le>n"}.*}
+
+lemma eq_number_of_0 [simp]:
+ "number_of v = (0::nat) \<longleftrightarrow> v \<le> Int.Pls"
+ unfolding nat_number_of_def number_of_is_id numeral_simps
+ by auto
+
+lemma eq_0_number_of [simp]:
+ "(0::nat) = number_of v \<longleftrightarrow> v \<le> Int.Pls"
+by (rule trans [OF eq_sym_conv eq_number_of_0])
+
+lemma less_0_number_of [simp]:
+ "(0::nat) < number_of v \<longleftrightarrow> Int.Pls < v"
+ unfolding nat_number_of_def number_of_is_id numeral_simps
+ by simp
+
+lemma neg_imp_number_of_eq_0: "neg (number_of v :: int) ==> number_of v = (0::nat)"
+by (simp del: nat_numeral_0_eq_0 add: nat_numeral_0_eq_0 [symmetric])
+
+
+
+subsection{*Comparisons involving @{term Suc} *}
+
+lemma eq_number_of_Suc [simp]:
+ "(number_of v = Suc n) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then False else nat pv = n)"
+apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less
+ number_of_pred nat_number_of_def
+ split add: split_if)
+apply (rule_tac x = "number_of v" in spec)
+apply (auto simp add: nat_eq_iff)
+done
+
+lemma Suc_eq_number_of [simp]:
+ "(Suc n = number_of v) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then False else nat pv = n)"
+by (rule trans [OF eq_sym_conv eq_number_of_Suc])
+
+lemma less_number_of_Suc [simp]:
+ "(number_of v < Suc n) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then True else nat pv < n)"
+apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less
+ number_of_pred nat_number_of_def
+ split add: split_if)
+apply (rule_tac x = "number_of v" in spec)
+apply (auto simp add: nat_less_iff)
+done
+
+lemma less_Suc_number_of [simp]:
+ "(Suc n < number_of v) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then False else n < nat pv)"
+apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less
+ number_of_pred nat_number_of_def
+ split add: split_if)
+apply (rule_tac x = "number_of v" in spec)
+apply (auto simp add: zless_nat_eq_int_zless)
+done
+
+lemma le_number_of_Suc [simp]:
+ "(number_of v <= Suc n) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then True else nat pv <= n)"
+by (simp add: Let_def less_Suc_number_of linorder_not_less [symmetric])
+
+lemma le_Suc_number_of [simp]:
+ "(Suc n <= number_of v) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then False else n <= nat pv)"
+by (simp add: Let_def less_number_of_Suc linorder_not_less [symmetric])
+
+
+lemma eq_number_of_Pls_Min: "(Numeral0 ::int) ~= number_of Int.Min"
+by auto
+
+
+
+subsection{*Max and Min Combined with @{term Suc} *}
+
+lemma max_number_of_Suc [simp]:
+ "max (Suc n) (number_of v) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then Suc n else Suc(max n (nat pv)))"
+apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def
+ split add: split_if nat.split)
+apply (rule_tac x = "number_of v" in spec)
+apply auto
+done
+
+lemma max_Suc_number_of [simp]:
+ "max (number_of v) (Suc n) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then Suc n else Suc(max (nat pv) n))"
+apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def
+ split add: split_if nat.split)
+apply (rule_tac x = "number_of v" in spec)
+apply auto
+done
+
+lemma min_number_of_Suc [simp]:
+ "min (Suc n) (number_of v) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then 0 else Suc(min n (nat pv)))"
+apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def
+ split add: split_if nat.split)
+apply (rule_tac x = "number_of v" in spec)
+apply auto
+done
+
+lemma min_Suc_number_of [simp]:
+ "min (number_of v) (Suc n) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then 0 else Suc(min (nat pv) n))"
+apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def
+ split add: split_if nat.split)
+apply (rule_tac x = "number_of v" in spec)
+apply auto
+done
+
+subsection{*Literal arithmetic involving powers*}
+
+lemma nat_power_eq: "(0::int) <= z ==> nat (z^n) = nat z ^ n"
+apply (induct "n")
+apply (simp_all (no_asm_simp) add: nat_mult_distrib)
+done
+
+lemma power_nat_number_of:
+ "(number_of v :: nat) ^ n =
+ (if neg (number_of v :: int) then 0^n else nat ((number_of v :: int) ^ n))"
+by (simp only: simp_thms neg_nat not_neg_eq_ge_0 nat_number_of_def nat_power_eq
+ split add: split_if cong: imp_cong)
+
+
+lemmas power_nat_number_of_number_of = power_nat_number_of [of _ "number_of w", standard]
+declare power_nat_number_of_number_of [simp]
+
+
+
+text{*For arbitrary rings*}
+
+lemma power_number_of_even:
+ fixes z :: "'a::number_ring"
+ shows "z ^ number_of (Int.Bit0 w) = (let w = z ^ (number_of w) in w * w)"
+unfolding Let_def nat_number_of_def number_of_Bit0
+apply (rule_tac x = "number_of w" in spec, clarify)
+apply (case_tac " (0::int) <= x")
+apply (auto simp add: nat_mult_distrib power_even_eq power2_eq_square)
+done
+
+lemma power_number_of_odd:
+ fixes z :: "'a::number_ring"
+ shows "z ^ number_of (Int.Bit1 w) = (if (0::int) <= number_of w
+ then (let w = z ^ (number_of w) in z * w * w) else 1)"
+unfolding Let_def nat_number_of_def number_of_Bit1
+apply (rule_tac x = "number_of w" in spec, auto)
+apply (simp only: nat_add_distrib nat_mult_distrib)
+apply simp
+apply (auto simp add: nat_add_distrib nat_mult_distrib power_even_eq power2_eq_square neg_nat power_Suc)
+done
+
+lemmas zpower_number_of_even = power_number_of_even [where 'a=int]
+lemmas zpower_number_of_odd = power_number_of_odd [where 'a=int]
+
+lemmas power_number_of_even_number_of [simp] =
+ power_number_of_even [of "number_of v", standard]
+
+lemmas power_number_of_odd_number_of [simp] =
+ power_number_of_odd [of "number_of v", standard]
+
+
+(* Enable arith to deal with div/mod k where k is a numeral: *)
+declare split_div[of _ _ "number_of k", standard, arith_split]
+declare split_mod[of _ _ "number_of k", standard, arith_split]
+
+lemma nat_number_of_Pls: "Numeral0 = (0::nat)"
+ by (simp add: number_of_Pls nat_number_of_def)
+
+lemma nat_number_of_Min: "number_of Int.Min = (0::nat)"
+ apply (simp only: number_of_Min nat_number_of_def nat_zminus_int)
+ done
+
+lemma nat_number_of_Bit0:
+ "number_of (Int.Bit0 w) = (let n::nat = number_of w in n + n)"
+ unfolding nat_number_of_def number_of_is_id numeral_simps Let_def
+ by auto
+
+lemma nat_number_of_Bit1:
+ "number_of (Int.Bit1 w) =
+ (if neg (number_of w :: int) then 0
+ else let n = number_of w in Suc (n + n))"
+ unfolding nat_number_of_def number_of_is_id numeral_simps neg_def Let_def
+ by auto
+
+lemmas nat_number =
+ nat_number_of_Pls nat_number_of_Min
+ nat_number_of_Bit0 nat_number_of_Bit1
+
+lemma Let_Suc [simp]: "Let (Suc n) f == f (Suc n)"
+ by (simp add: Let_def)
+
+lemma power_m1_even: "(-1) ^ (2*n) = (1::'a::{number_ring})"
+ by (simp only: number_of_Min power_minus1_even)
+
+lemma power_m1_odd: "(-1) ^ Suc(2*n) = (-1::'a::{number_ring})"
+ by (simp only: number_of_Min power_minus1_odd)
+
+
+subsection{*Literal arithmetic and @{term of_nat}*}
+
+lemma of_nat_double:
+ "0 \<le> x ==> of_nat (nat (2 * x)) = of_nat (nat x) + of_nat (nat x)"
+by (simp only: mult_2 nat_add_distrib of_nat_add)
+
+lemma nat_numeral_m1_eq_0: "-1 = (0::nat)"
+by (simp only: nat_number_of_def)
+
+lemma of_nat_number_of_lemma:
+ "of_nat (number_of v :: nat) =
+ (if 0 \<le> (number_of v :: int)
+ then (number_of v :: 'a :: number_ring)
+ else 0)"
+by (simp add: int_number_of_def nat_number_of_def number_of_eq of_nat_nat);
+
+lemma of_nat_number_of_eq [simp]:
+ "of_nat (number_of v :: nat) =
+ (if neg (number_of v :: int) then 0
+ else (number_of v :: 'a :: number_ring))"
+by (simp only: of_nat_number_of_lemma neg_def, simp)
+
+
+subsection {*Lemmas for the Combination and Cancellation Simprocs*}
+
+lemma nat_number_of_add_left:
+ "number_of v + (number_of v' + (k::nat)) =
+ (if neg (number_of v :: int) then number_of v' + k
+ else if neg (number_of v' :: int) then number_of v + k
+ else number_of (v + v') + k)"
+ unfolding nat_number_of_def number_of_is_id neg_def
+ by auto
+
+lemma nat_number_of_mult_left:
+ "number_of v * (number_of v' * (k::nat)) =
+ (if v < Int.Pls then 0
+ else number_of (v * v') * k)"
+by simp
+
+
+subsubsection{*For @{text combine_numerals}*}
+
+lemma left_add_mult_distrib: "i*u + (j*u + k) = (i+j)*u + (k::nat)"
+by (simp add: add_mult_distrib)
+
+
+subsubsection{*For @{text cancel_numerals}*}
+
+lemma nat_diff_add_eq1:
+ "j <= (i::nat) ==> ((i*u + m) - (j*u + n)) = (((i-j)*u + m) - n)"
+by (simp split add: nat_diff_split add: add_mult_distrib)
+
+lemma nat_diff_add_eq2:
+ "i <= (j::nat) ==> ((i*u + m) - (j*u + n)) = (m - ((j-i)*u + n))"
+by (simp split add: nat_diff_split add: add_mult_distrib)
+
+lemma nat_eq_add_iff1:
+ "j <= (i::nat) ==> (i*u + m = j*u + n) = ((i-j)*u + m = n)"
+by (auto split add: nat_diff_split simp add: add_mult_distrib)
+
+lemma nat_eq_add_iff2:
+ "i <= (j::nat) ==> (i*u + m = j*u + n) = (m = (j-i)*u + n)"
+by (auto split add: nat_diff_split simp add: add_mult_distrib)
+
+lemma nat_less_add_iff1:
+ "j <= (i::nat) ==> (i*u + m < j*u + n) = ((i-j)*u + m < n)"
+by (auto split add: nat_diff_split simp add: add_mult_distrib)
+
+lemma nat_less_add_iff2:
+ "i <= (j::nat) ==> (i*u + m < j*u + n) = (m < (j-i)*u + n)"
+by (auto split add: nat_diff_split simp add: add_mult_distrib)
+
+lemma nat_le_add_iff1:
+ "j <= (i::nat) ==> (i*u + m <= j*u + n) = ((i-j)*u + m <= n)"
+by (auto split add: nat_diff_split simp add: add_mult_distrib)
+
+lemma nat_le_add_iff2:
+ "i <= (j::nat) ==> (i*u + m <= j*u + n) = (m <= (j-i)*u + n)"
+by (auto split add: nat_diff_split simp add: add_mult_distrib)
+
+
+subsubsection{*For @{text cancel_numeral_factors} *}
+
+lemma nat_mult_le_cancel1: "(0::nat) < k ==> (k*m <= k*n) = (m<=n)"
+by auto
+
+lemma nat_mult_less_cancel1: "(0::nat) < k ==> (k*m < k*n) = (m<n)"
+by auto
+
+lemma nat_mult_eq_cancel1: "(0::nat) < k ==> (k*m = k*n) = (m=n)"
+by auto
+
+lemma nat_mult_div_cancel1: "(0::nat) < k ==> (k*m) div (k*n) = (m div n)"
+by auto
+
+lemma nat_mult_dvd_cancel_disj[simp]:
+ "(k*m) dvd (k*n) = (k=0 | m dvd (n::nat))"
+by(auto simp: dvd_eq_mod_eq_0 mod_mult_distrib2[symmetric])
+
+lemma nat_mult_dvd_cancel1: "0 < k \<Longrightarrow> (k*m) dvd (k*n::nat) = (m dvd n)"
+by(auto)
+
+
+subsubsection{*For @{text cancel_factor} *}
+
+lemma nat_mult_le_cancel_disj: "(k*m <= k*n) = ((0::nat) < k --> m<=n)"
+by auto
+
+lemma nat_mult_less_cancel_disj: "(k*m < k*n) = ((0::nat) < k & m<n)"
+by auto
+
+lemma nat_mult_eq_cancel_disj: "(k*m = k*n) = (k = (0::nat) | m=n)"
+by auto
+
+lemma nat_mult_div_cancel_disj[simp]:
+ "(k*m) div (k*n) = (if k = (0::nat) then 0 else m div n)"
+by (simp add: nat_mult_div_cancel1)
+
+
+subsection {* Simprocs for the Naturals *}
+
+use "Tools/nat_numeral_simprocs.ML"
+
+declaration {*
+let
+
+val less_eq_rules = @{thms ring_distribs} @
+ [@{thm Let_number_of}, @{thm Let_0}, @{thm Let_1}, @{thm nat_0}, @{thm nat_1},
+ @{thm add_nat_number_of}, @{thm diff_nat_number_of}, @{thm mult_nat_number_of},
+ @{thm eq_nat_number_of}, @{thm less_nat_number_of}, @{thm le_number_of_eq_not_less},
+ @{thm le_Suc_number_of}, @{thm le_number_of_Suc},
+ @{thm less_Suc_number_of}, @{thm less_number_of_Suc},
+ @{thm Suc_eq_number_of}, @{thm eq_number_of_Suc},
+ @{thm mult_Suc}, @{thm mult_Suc_right},
+ @{thm add_Suc}, @{thm add_Suc_right},
+ @{thm eq_number_of_0}, @{thm eq_0_number_of}, @{thm less_0_number_of},
+ @{thm of_int_number_of_eq}, @{thm of_nat_number_of_eq}, @{thm nat_number_of}, @{thm if_True}, @{thm if_False}];
+
+val simprocs = Nat_Numeral_Simprocs.combine_numerals :: Nat_Numeral_Simprocs.cancel_numerals;
+
+in
+
+K (Lin_Arith.map_data (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset} =>
+ {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms,
+ inj_thms = inj_thms, lessD = lessD, neqE = neqE,
+ simpset = simpset addsimps (@{thms neg_simps} @ [@{thm Suc_nat_number_of}, @{thm int_nat_number_of}])
+ addsimps less_eq_rules
+ addsimprocs simprocs}))
+
+end
+*}
+
+
+subsubsection{*For simplifying @{term "Suc m - K"} and @{term "K - Suc m"}*}
+
+text{*Where K above is a literal*}
+
+lemma Suc_diff_eq_diff_pred: "Numeral0 < n ==> Suc m - n = m - (n - Numeral1)"
+by (simp add: numeral_0_eq_0 numeral_1_eq_1 split add: nat_diff_split)
+
+text {*Now just instantiating @{text n} to @{text "number_of v"} does
+ the right simplification, but with some redundant inequality
+ tests.*}
+lemma neg_number_of_pred_iff_0:
+ "neg (number_of (Int.pred v)::int) = (number_of v = (0::nat))"
+apply (subgoal_tac "neg (number_of (Int.pred v)) = (number_of v < Suc 0) ")
+apply (simp only: less_Suc_eq_le le_0_eq)
+apply (subst less_number_of_Suc, simp)
+done
+
+text{*No longer required as a simprule because of the @{text inverse_fold}
+ simproc*}
+lemma Suc_diff_number_of:
+ "Int.Pls < v ==>
+ Suc m - (number_of v) = m - (number_of (Int.pred v))"
+apply (subst Suc_diff_eq_diff_pred)
+apply simp
+apply (simp del: nat_numeral_1_eq_1)
+apply (auto simp only: diff_nat_number_of less_0_number_of [symmetric]
+ neg_number_of_pred_iff_0)
+done
+
+lemma diff_Suc_eq_diff_pred: "m - Suc n = (m - 1) - n"
+by (simp add: numerals split add: nat_diff_split)
+
+
+subsubsection{*For @{term nat_case} and @{term nat_rec}*}
+
+lemma nat_case_number_of [simp]:
+ "nat_case a f (number_of v) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then a else f (nat pv))"
+by (simp split add: nat.split add: Let_def neg_number_of_pred_iff_0)
+
+lemma nat_case_add_eq_if [simp]:
+ "nat_case a f ((number_of v) + n) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then nat_case a f n else f (nat pv + n))"
+apply (subst add_eq_if)
+apply (simp split add: nat.split
+ del: nat_numeral_1_eq_1
+ add: nat_numeral_1_eq_1 [symmetric]
+ numeral_1_eq_Suc_0 [symmetric]
+ neg_number_of_pred_iff_0)
+done
+
+lemma nat_rec_number_of [simp]:
+ "nat_rec a f (number_of v) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then a else f (nat pv) (nat_rec a f (nat pv)))"
+apply (case_tac " (number_of v) ::nat")
+apply (simp_all (no_asm_simp) add: Let_def neg_number_of_pred_iff_0)
+apply (simp split add: split_if_asm)
+done
+
+lemma nat_rec_add_eq_if [simp]:
+ "nat_rec a f (number_of v + n) =
+ (let pv = number_of (Int.pred v) in
+ if neg pv then nat_rec a f n
+ else f (nat pv + n) (nat_rec a f (nat pv + n)))"
+apply (subst add_eq_if)
+apply (simp split add: nat.split
+ del: nat_numeral_1_eq_1
+ add: nat_numeral_1_eq_1 [symmetric]
+ numeral_1_eq_Suc_0 [symmetric]
+ neg_number_of_pred_iff_0)
+done
+
+
+subsubsection{*Various Other Lemmas*}
+
+lemma card_UNIV_bool[simp]: "card (UNIV :: bool set) = 2"
+by(simp add: UNIV_bool)
+
+text {*Evens and Odds, for Mutilated Chess Board*}
+
+text{*Lemmas for specialist use, NOT as default simprules*}
+lemma nat_mult_2: "2 * z = (z+z::nat)"
+proof -
+ have "2*z = (1 + 1)*z" by simp
+ also have "... = z+z" by (simp add: left_distrib)
+ finally show ?thesis .
+qed
+
+lemma nat_mult_2_right: "z * 2 = (z+z::nat)"
+by (subst mult_commute, rule nat_mult_2)
+
+text{*Case analysis on @{term "n<2"}*}
+lemma less_2_cases: "(n::nat) < 2 ==> n = 0 | n = Suc 0"
+by arith
+
+lemma div2_Suc_Suc [simp]: "Suc(Suc m) div 2 = Suc (m div 2)"
+by arith
+
+lemma add_self_div_2 [simp]: "(m + m) div 2 = (m::nat)"
+by (simp add: nat_mult_2 [symmetric])
+
+lemma mod2_Suc_Suc [simp]: "Suc(Suc(m)) mod 2 = m mod 2"
+apply (subgoal_tac "m mod 2 < 2")
+apply (erule less_2_cases [THEN disjE])
+apply (simp_all (no_asm_simp) add: Let_def mod_Suc nat_1)
+done
+
+lemma mod2_gr_0 [simp]: "!!m::nat. (0 < m mod 2) = (m mod 2 = 1)"
+apply (subgoal_tac "m mod 2 < 2")
+apply (force simp del: mod_less_divisor, simp)
+done
+
+text{*Removal of Small Numerals: 0, 1 and (in additive positions) 2*}
+
+lemma add_2_eq_Suc [simp]: "2 + n = Suc (Suc n)"
+by simp
+
+lemma add_2_eq_Suc' [simp]: "n + 2 = Suc (Suc n)"
+by simp
+
+text{*Can be used to eliminate long strings of Sucs, but not by default*}
+lemma Suc3_eq_add_3: "Suc (Suc (Suc n)) = 3 + n"
+by simp
+
+
+text{*These lemmas collapse some needless occurrences of Suc:
+ at least three Sucs, since two and fewer are rewritten back to Suc again!
+ We already have some rules to simplify operands smaller than 3.*}
+
+lemma div_Suc_eq_div_add3 [simp]: "m div (Suc (Suc (Suc n))) = m div (3+n)"
+by (simp add: Suc3_eq_add_3)
+
+lemma mod_Suc_eq_mod_add3 [simp]: "m mod (Suc (Suc (Suc n))) = m mod (3+n)"
+by (simp add: Suc3_eq_add_3)
+
+lemma Suc_div_eq_add3_div: "(Suc (Suc (Suc m))) div n = (3+m) div n"
+by (simp add: Suc3_eq_add_3)
+
+lemma Suc_mod_eq_add3_mod: "(Suc (Suc (Suc m))) mod n = (3+m) mod n"
+by (simp add: Suc3_eq_add_3)
+
+lemmas Suc_div_eq_add3_div_number_of =
+ Suc_div_eq_add3_div [of _ "number_of v", standard]
+declare Suc_div_eq_add3_div_number_of [simp]
+
+lemmas Suc_mod_eq_add3_mod_number_of =
+ Suc_mod_eq_add3_mod [of _ "number_of v", standard]
+declare Suc_mod_eq_add3_mod_number_of [simp]
+
+end
\ No newline at end of file
--- a/src/HOL/Nominal/Examples/Fsub.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Nominal/Examples/Fsub.thy Mon May 11 17:20:52 2009 +0200
@@ -245,7 +245,7 @@
apply (simp add: dj_perm_forget[OF dj_tyvrs_vrs])
done
-lemma ty_vrs_fresh[fresh]:
+lemma ty_vrs_fresh:
fixes x::"vrs"
and T::"ty"
shows "x \<sharp> T"
@@ -422,7 +422,7 @@
by (nominal_induct T avoiding: X T' rule: ty.strong_induct)
(perm_simp add: fresh_left)+
-lemma type_subst_fresh[fresh]:
+lemma type_subst_fresh:
fixes X::"tyvrs"
assumes "X \<sharp> T" and "X \<sharp> P"
shows "X \<sharp> T[Y \<mapsto> P]\<^sub>\<tau>"
@@ -430,7 +430,7 @@
by (nominal_induct T avoiding: X Y P rule:ty.strong_induct)
(auto simp add: abs_fresh)
-lemma fresh_type_subst_fresh[fresh]:
+lemma fresh_type_subst_fresh:
assumes "X\<sharp>T'"
shows "X\<sharp>T[X \<mapsto> T']\<^sub>\<tau>"
using assms
@@ -458,18 +458,19 @@
| "(VarB X U)[Y \<mapsto> T]\<^sub>b = VarB X (U[Y \<mapsto> T]\<^sub>\<tau>)"
by auto
-lemma binding_subst_fresh[fresh]:
+lemma binding_subst_fresh:
fixes X::"tyvrs"
assumes "X \<sharp> a"
and "X \<sharp> P"
shows "X \<sharp> a[Y \<mapsto> P]\<^sub>b"
using assms
-by (nominal_induct a rule:binding.strong_induct)
- (auto simp add: freshs)
+by (nominal_induct a rule: binding.strong_induct)
+ (auto simp add: type_subst_fresh)
-lemma binding_subst_identity: "X \<sharp> B \<Longrightarrow> B[X \<mapsto> U]\<^sub>b = B"
- by (induct B rule: binding.induct)
- (simp_all add: fresh_atm type_subst_identity)
+lemma binding_subst_identity:
+ shows "X \<sharp> B \<Longrightarrow> B[X \<mapsto> U]\<^sub>b = B"
+by (induct B rule: binding.induct)
+ (simp_all add: fresh_atm type_subst_identity)
consts
subst_tyc :: "env \<Rightarrow> tyvrs \<Rightarrow> ty \<Rightarrow> env" ("_[_ \<mapsto> _]\<^sub>e" [100,100,100] 100)
@@ -478,14 +479,14 @@
"([])[Y \<mapsto> T]\<^sub>e= []"
"(B#\<Gamma>)[Y \<mapsto> T]\<^sub>e = (B[Y \<mapsto> T]\<^sub>b)#(\<Gamma>[Y \<mapsto> T]\<^sub>e)"
-lemma ctxt_subst_fresh'[fresh]:
+lemma ctxt_subst_fresh':
fixes X::"tyvrs"
assumes "X \<sharp> \<Gamma>"
and "X \<sharp> P"
shows "X \<sharp> \<Gamma>[Y \<mapsto> P]\<^sub>e"
using assms
by (induct \<Gamma>)
- (auto simp add: fresh_list_cons freshs)
+ (auto simp add: fresh_list_cons binding_subst_fresh)
lemma ctxt_subst_mem_TVarB: "TVarB X T \<in> set \<Gamma> \<Longrightarrow> TVarB X (T[Y \<mapsto> U]\<^sub>\<tau>) \<in> set (\<Gamma>[Y \<mapsto> U]\<^sub>e)"
by (induct \<Gamma>) auto
@@ -1188,8 +1189,8 @@
using assms by (induct, auto)
nominal_inductive typing
- by (auto dest!: typing_ok intro: closed_in_fresh fresh_domain
- simp: abs_fresh fresh_prod fresh_atm freshs valid_ty_domain_fresh fresh_trm_domain)
+by (auto dest!: typing_ok intro: closed_in_fresh fresh_domain type_subst_fresh
+ simp: abs_fresh fresh_type_subst_fresh ty_vrs_fresh valid_ty_domain_fresh fresh_trm_domain)
lemma ok_imp_VarB_closed_in:
assumes ok: "\<turnstile> \<Gamma> ok"
--- a/src/HOL/Nominal/Nominal.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Nominal/Nominal.thy Mon May 11 17:20:52 2009 +0200
@@ -18,25 +18,98 @@
types
'x prm = "('x \<times> 'x) list"
-(* polymorphic operations for permutation and swapping *)
+(* polymorphic constants for permutation and swapping *)
consts
perm :: "'x prm \<Rightarrow> 'a \<Rightarrow> 'a" (infixr "\<bullet>" 80)
swap :: "('x \<times> 'x) \<Rightarrow> 'x \<Rightarrow> 'x"
+(* a "private" copy of the option type used in the abstraction function *)
+datatype 'a noption = nSome 'a | nNone
+
+(* a "private" copy of the product type used in the nominal induct method *)
+datatype ('a,'b) nprod = nPair 'a 'b
+
(* an auxiliary constant for the decision procedure involving *)
-(* permutations (to avoid loops when using perm-composition) *)
+(* permutations (to avoid loops when using perm-compositions) *)
constdefs
"perm_aux pi x \<equiv> pi\<bullet>x"
-(* permutation on functions *)
-defs (unchecked overloaded)
- perm_fun_def: "pi\<bullet>(f::'a\<Rightarrow>'b) \<equiv> (\<lambda>x. pi\<bullet>f((rev pi)\<bullet>x))"
-
-(* permutation on bools *)
-primrec (unchecked perm_bool)
- true_eqvt: "pi\<bullet>True = True"
- false_eqvt: "pi\<bullet>False = False"
-
+(* overloaded permutation operations *)
+overloading
+ perm_fun \<equiv> "perm :: 'x prm \<Rightarrow> ('a\<Rightarrow>'b) \<Rightarrow> ('a\<Rightarrow>'b)" (unchecked)
+ perm_bool \<equiv> "perm :: 'x prm \<Rightarrow> bool \<Rightarrow> bool" (unchecked)
+ perm_unit \<equiv> "perm :: 'x prm \<Rightarrow> unit \<Rightarrow> unit" (unchecked)
+ perm_prod \<equiv> "perm :: 'x prm \<Rightarrow> ('a\<times>'b) \<Rightarrow> ('a\<times>'b)" (unchecked)
+ perm_list \<equiv> "perm :: 'x prm \<Rightarrow> 'a list \<Rightarrow> 'a list" (unchecked)
+ perm_option \<equiv> "perm :: 'x prm \<Rightarrow> 'a option \<Rightarrow> 'a option" (unchecked)
+ perm_char \<equiv> "perm :: 'x prm \<Rightarrow> char \<Rightarrow> char" (unchecked)
+ perm_nat \<equiv> "perm :: 'x prm \<Rightarrow> nat \<Rightarrow> nat" (unchecked)
+ perm_int \<equiv> "perm :: 'x prm \<Rightarrow> int \<Rightarrow> int" (unchecked)
+
+ perm_noption \<equiv> "perm :: 'x prm \<Rightarrow> 'a noption \<Rightarrow> 'a noption" (unchecked)
+ perm_nprod \<equiv> "perm :: 'x prm \<Rightarrow> ('a, 'b) nprod \<Rightarrow> ('a, 'b) nprod" (unchecked)
+begin
+
+definition
+ perm_fun_def: "perm_fun pi (f::'a\<Rightarrow>'b) \<equiv> (\<lambda>x. pi\<bullet>f((rev pi)\<bullet>x))"
+
+fun
+ perm_bool :: "'x prm \<Rightarrow> bool \<Rightarrow> bool"
+where
+ true_eqvt: "perm_bool pi True = True"
+| false_eqvt: "perm_bool pi False = False"
+
+fun
+ perm_unit :: "'x prm \<Rightarrow> unit \<Rightarrow> unit"
+where
+ "perm_unit pi () = ()"
+
+fun
+ perm_prod :: "'x prm \<Rightarrow> ('a\<times>'b) \<Rightarrow> ('a\<times>'b)"
+where
+ "perm_prod pi (x,y) = (pi\<bullet>x,pi\<bullet>y)"
+
+fun
+ perm_list :: "'x prm \<Rightarrow> 'a list \<Rightarrow> 'a list"
+where
+ nil_eqvt: "perm_list pi [] = []"
+| cons_eqvt: "perm_list pi (x#xs) = (pi\<bullet>x)#(pi\<bullet>xs)"
+
+fun
+ perm_option :: "'x prm \<Rightarrow> 'a option \<Rightarrow> 'a option"
+where
+ some_eqvt: "perm_option pi (Some x) = Some (pi\<bullet>x)"
+| none_eqvt: "perm_option pi None = None"
+
+definition
+ perm_char :: "'x prm \<Rightarrow> char \<Rightarrow> char"
+where
+ perm_char_def: "perm_char pi c \<equiv> c"
+
+definition
+ perm_nat :: "'x prm \<Rightarrow> nat \<Rightarrow> nat"
+where
+ perm_nat_def: "perm_nat pi i \<equiv> i"
+
+definition
+ perm_int :: "'x prm \<Rightarrow> int \<Rightarrow> int"
+where
+ perm_int_def: "perm_int pi i \<equiv> i"
+
+fun
+ perm_noption :: "'x prm \<Rightarrow> 'a noption \<Rightarrow> 'a noption"
+where
+ nsome_eqvt: "perm_noption pi (nSome x) = nSome (pi\<bullet>x)"
+| nnone_eqvt: "perm_noption pi nNone = nNone"
+
+fun
+ perm_nprod :: "'x prm \<Rightarrow> ('a, 'b) nprod \<Rightarrow> ('a, 'b) nprod"
+where
+ "perm_nprod pi (nPair x y) = nPair (pi\<bullet>x) (pi\<bullet>y)"
+end
+
+
+(* permutations on booleans *)
lemma perm_bool:
shows "pi\<bullet>(b::bool) = b"
by (cases b) auto
@@ -54,8 +127,7 @@
lemma if_eqvt:
fixes pi::"'a prm"
shows "pi\<bullet>(if b then c1 else c2) = (if (pi\<bullet>b) then (pi\<bullet>c1) else (pi\<bullet>c2))"
-apply(simp add: perm_fun_def)
-done
+ by (simp add: perm_fun_def)
lemma imp_eqvt:
shows "pi\<bullet>(A\<longrightarrow>B) = ((pi\<bullet>A)\<longrightarrow>(pi\<bullet>B))"
@@ -82,13 +154,7 @@
shows "(pi\<bullet>(X\<union>Y)) = (pi\<bullet>X) \<union> (pi\<bullet>Y)"
by (simp add: perm_fun_def perm_bool Un_iff [unfolded mem_def] expand_fun_eq)
-(* permutation on units and products *)
-primrec (unchecked perm_unit)
- "pi\<bullet>() = ()"
-
-primrec (unchecked perm_prod)
- "pi\<bullet>(x,y) = (pi\<bullet>x,pi\<bullet>y)"
-
+(* permutations on products *)
lemma fst_eqvt:
"pi\<bullet>(fst x) = fst (pi\<bullet>x)"
by (cases x) simp
@@ -98,10 +164,6 @@
by (cases x) simp
(* permutation on lists *)
-primrec (unchecked perm_list)
- nil_eqvt: "pi\<bullet>[] = []"
- cons_eqvt: "pi\<bullet>(x#xs) = (pi\<bullet>x)#(pi\<bullet>xs)"
-
lemma append_eqvt:
fixes pi :: "'x prm"
and l1 :: "'a list"
@@ -115,41 +177,12 @@
shows "pi\<bullet>(rev l) = rev (pi\<bullet>l)"
by (induct l) (simp_all add: append_eqvt)
-(* permutation on options *)
-
-primrec (unchecked perm_option)
- some_eqvt: "pi\<bullet>Some(x) = Some(pi\<bullet>x)"
- none_eqvt: "pi\<bullet>None = None"
-
-(* a "private" copy of the option type used in the abstraction function *)
-datatype 'a noption = nSome 'a | nNone
-
-primrec (unchecked perm_noption)
- nSome_eqvt: "pi\<bullet>nSome(x) = nSome(pi\<bullet>x)"
- nNone_eqvt: "pi\<bullet>nNone = nNone"
-
-(* a "private" copy of the product type used in the nominal induct method *)
-datatype ('a,'b) nprod = nPair 'a 'b
-
-primrec (unchecked perm_nprod)
- perm_nProd_def: "pi\<bullet>(nPair x1 x2) = nPair (pi\<bullet>x1) (pi\<bullet>x2)"
-
-(* permutation on characters (used in strings) *)
-defs (unchecked overloaded)
- perm_char_def: "pi\<bullet>(c::char) \<equiv> c"
-
+(* permutation on characters and strings *)
lemma perm_string:
fixes s::"string"
shows "pi\<bullet>s = s"
-by (induct s)(auto simp add: perm_char_def)
-
-(* permutation on ints *)
-defs (unchecked overloaded)
- perm_int_def: "pi\<bullet>(i::int) \<equiv> i"
-
-(* permutation on nats *)
-defs (unchecked overloaded)
- perm_nat_def: "pi\<bullet>(i::nat) \<equiv> i"
+ by (induct s)(auto simp add: perm_char_def)
+
section {* permutation equality *}
(*==============================*)
@@ -170,11 +203,12 @@
supports :: "'x set \<Rightarrow> 'a \<Rightarrow> bool" (infixl "supports" 80)
"S supports x \<equiv> \<forall>a b. (a\<notin>S \<and> b\<notin>S \<longrightarrow> [(a,b)]\<bullet>x=x)"
+(* lemmas about supp *)
lemma supp_fresh_iff:
fixes x :: "'a"
shows "(supp x) = {a::'x. \<not>a\<sharp>x}"
-apply(simp add: fresh_def)
-done
+ by (simp add: fresh_def)
+
lemma supp_unit:
shows "supp () = {}"
@@ -205,14 +239,13 @@
fixes x :: "'a"
and xs :: "'a list"
shows "supp (x#xs) = (supp x)\<union>(supp xs)"
-apply(auto simp add: supp_def Collect_imp_eq Collect_neg_eq)
-done
+ by (auto simp add: supp_def Collect_imp_eq Collect_neg_eq)
lemma supp_list_append:
fixes xs :: "'a list"
and ys :: "'a list"
shows "supp (xs@ys) = (supp xs)\<union>(supp ys)"
- by (induct xs, auto simp add: supp_list_nil supp_list_cons)
+ by (induct xs) (auto simp add: supp_list_nil supp_list_cons)
lemma supp_list_rev:
fixes xs :: "'a list"
@@ -221,47 +254,40 @@
lemma supp_bool:
fixes x :: "bool"
- shows "supp (x) = {}"
- apply(case_tac "x")
- apply(simp_all add: supp_def)
-done
+ shows "supp x = {}"
+ by (cases "x") (simp_all add: supp_def)
lemma supp_some:
fixes x :: "'a"
shows "supp (Some x) = (supp x)"
- apply(simp add: supp_def)
- done
+ by (simp add: supp_def)
lemma supp_none:
fixes x :: "'a"
shows "supp (None) = {}"
- apply(simp add: supp_def)
- done
+ by (simp add: supp_def)
lemma supp_int:
fixes i::"int"
shows "supp (i) = {}"
- apply(simp add: supp_def perm_int_def)
- done
+ by (simp add: supp_def perm_int_def)
lemma supp_nat:
fixes n::"nat"
- shows "supp (n) = {}"
- apply(simp add: supp_def perm_nat_def)
- done
+ shows "(supp n) = {}"
+ by (simp add: supp_def perm_nat_def)
lemma supp_char:
fixes c::"char"
- shows "supp (c) = {}"
- apply(simp add: supp_def perm_char_def)
- done
+ shows "(supp c) = {}"
+ by (simp add: supp_def perm_char_def)
lemma supp_string:
fixes s::"string"
- shows "supp (s) = {}"
-apply(simp add: supp_def perm_string)
-done
-
+ shows "(supp s) = {}"
+ by (simp add: supp_def perm_string)
+
+(* lemmas about freshness *)
lemma fresh_set_empty:
shows "a\<sharp>{}"
by (simp add: fresh_def supp_set_empty)
@@ -344,7 +370,6 @@
by (simp add: fresh_def supp_bool)
text {* Normalization of freshness results; cf.\ @{text nominal_induct} *}
-
lemma fresh_unit_elim:
shows "(a\<sharp>() \<Longrightarrow> PROP C) \<equiv> PROP C"
by (simp add: fresh_def supp_unit)
@@ -371,63 +396,6 @@
Simplifier.map_ss (fn ss => ss setmksimps (mksimps mksimps_pairs))
*}
-section {* generalisation of freshness to lists and sets of atoms *}
-(*================================================================*)
-
-consts
- fresh_star :: "'b \<Rightarrow> 'a \<Rightarrow> bool" ("_ \<sharp>* _" [100,100] 100)
-
-defs (overloaded)
- fresh_star_set: "xs\<sharp>*c \<equiv> \<forall>x\<in>xs. x\<sharp>c"
-
-defs (overloaded)
- fresh_star_list: "xs\<sharp>*c \<equiv> \<forall>x\<in>set xs. x\<sharp>c"
-
-lemmas fresh_star_def = fresh_star_list fresh_star_set
-
-lemma fresh_star_prod_set:
- fixes xs::"'a set"
- shows "xs\<sharp>*(a,b) = (xs\<sharp>*a \<and> xs\<sharp>*b)"
-by (auto simp add: fresh_star_def fresh_prod)
-
-lemma fresh_star_prod_list:
- fixes xs::"'a list"
- shows "xs\<sharp>*(a,b) = (xs\<sharp>*a \<and> xs\<sharp>*b)"
-by (auto simp add: fresh_star_def fresh_prod)
-
-lemmas fresh_star_prod = fresh_star_prod_list fresh_star_prod_set
-
-lemma fresh_star_set_eq: "set xs \<sharp>* c = xs \<sharp>* c"
- by (simp add: fresh_star_def)
-
-lemma fresh_star_Un_elim:
- "((S \<union> T) \<sharp>* c \<Longrightarrow> PROP C) \<equiv> (S \<sharp>* c \<Longrightarrow> T \<sharp>* c \<Longrightarrow> PROP C)"
- apply rule
- apply (simp_all add: fresh_star_def)
- apply (erule meta_mp)
- apply blast
- done
-
-lemma fresh_star_insert_elim:
- "(insert x S \<sharp>* c \<Longrightarrow> PROP C) \<equiv> (x \<sharp> c \<Longrightarrow> S \<sharp>* c \<Longrightarrow> PROP C)"
- by rule (simp_all add: fresh_star_def)
-
-lemma fresh_star_empty_elim:
- "({} \<sharp>* c \<Longrightarrow> PROP C) \<equiv> PROP C"
- by (simp add: fresh_star_def)
-
-text {* Normalization of freshness results; cf.\ @{text nominal_induct} *}
-
-lemma fresh_star_unit_elim:
- shows "((a::'a set)\<sharp>*() \<Longrightarrow> PROP C) \<equiv> PROP C"
- and "((b::'a list)\<sharp>*() \<Longrightarrow> PROP C) \<equiv> PROP C"
- by (simp_all add: fresh_star_def fresh_def supp_unit)
-
-lemma fresh_star_prod_elim:
- shows "((a::'a set)\<sharp>*(x,y) \<Longrightarrow> PROP C) \<equiv> (a\<sharp>*x \<Longrightarrow> a\<sharp>*y \<Longrightarrow> PROP C)"
- and "((b::'a list)\<sharp>*(x,y) \<Longrightarrow> PROP C) \<equiv> (b\<sharp>*x \<Longrightarrow> b\<sharp>*y \<Longrightarrow> PROP C)"
- by (rule, simp_all add: fresh_star_prod)+
-
section {* Abstract Properties for Permutations and Atoms *}
(*=========================================================*)
@@ -487,7 +455,7 @@
shows "swap (a,b) c = (if a=c then b else (if b=c then a else c))"
using a by (simp only: at_def)
-(* rules to calculate simple premutations *)
+(* rules to calculate simple permutations *)
lemmas at_calc = at2 at1 at3
lemma at_swap_simps:
@@ -682,7 +650,6 @@
shows "pi1 \<triangleq> pi2 \<Longrightarrow> (rev pi1) \<triangleq> (rev pi2)"
by (simp add: at_prm_rev_eq[OF at])
-
lemma at_ds1:
fixes a :: "'x"
assumes at: "at TYPE('x)"
@@ -838,15 +805,18 @@
by (auto intro: ex_in_inf[OF at, OF fs] simp add: fresh_def)
lemma at_finite_select:
- shows "at (TYPE('a)) \<Longrightarrow> finite (S::'a set) \<Longrightarrow> \<exists>x. x \<notin> S"
- apply (drule Diff_infinite_finite)
- apply (simp add: at_def)
- apply blast
- apply (subgoal_tac "UNIV - S \<noteq> {}")
- apply (simp only: ex_in_conv [symmetric])
- apply blast
- apply (rule notI)
- apply simp
+ fixes S::"'a set"
+ assumes a: "at TYPE('a)"
+ and b: "finite S"
+ shows "\<exists>x. x \<notin> S"
+ using a b
+ apply(drule_tac S="UNIV::'a set" in Diff_infinite_finite)
+ apply(simp add: at_def)
+ apply(subgoal_tac "UNIV - S \<noteq> {}")
+ apply(simp only: ex_in_conv [symmetric])
+ apply(blast)
+ apply(rule notI)
+ apply(simp)
done
lemma at_different:
@@ -1222,8 +1192,8 @@
assumes pt: "pt TYPE('a) TYPE('x)"
and at: "at TYPE('x)"
shows "pi\<bullet>(x=y) = (pi\<bullet>x = pi\<bullet>y)"
-using assms
-by (auto simp add: pt_bij perm_bool)
+ using pt at
+ by (auto simp add: pt_bij perm_bool)
lemma pt_bij3:
fixes pi :: "'x prm"
@@ -1231,7 +1201,7 @@
and y :: "'a"
assumes a: "x=y"
shows "(pi\<bullet>x = pi\<bullet>y)"
-using a by simp
+ using a by simp
lemma pt_bij4:
fixes pi :: "'x prm"
@@ -1241,7 +1211,7 @@
and at: "at TYPE('x)"
and a: "pi\<bullet>x = pi\<bullet>y"
shows "x = y"
-using a by (simp add: pt_bij[OF pt, OF at])
+ using a by (simp add: pt_bij[OF pt, OF at])
lemma pt_swap_bij:
fixes a :: "'x"
@@ -1574,35 +1544,6 @@
apply(simp add: pt_rev_pi[OF ptb, OF at])
done
-lemma pt_fresh_star_bij_ineq:
- fixes pi :: "'x prm"
- and x :: "'a"
- and a :: "'y set"
- and b :: "'y list"
- assumes pta: "pt TYPE('a) TYPE('x)"
- and ptb: "pt TYPE('y) TYPE('x)"
- and at: "at TYPE('x)"
- and cp: "cp TYPE('a) TYPE('x) TYPE('y)"
- shows "(pi\<bullet>a)\<sharp>*(pi\<bullet>x) = a\<sharp>*x"
- and "(pi\<bullet>b)\<sharp>*(pi\<bullet>x) = b\<sharp>*x"
-apply(unfold fresh_star_def)
-apply(auto)
-apply(drule_tac x="pi\<bullet>xa" in bspec)
-apply(rule pt_set_bij2[OF ptb, OF at])
-apply(assumption)
-apply(simp add: fresh_star_def pt_fresh_bij_ineq[OF pta, OF ptb, OF at, OF cp])
-apply(drule_tac x="(rev pi)\<bullet>xa" in bspec)
-apply(simp add: pt_set_bij1[OF ptb, OF at])
-apply(simp add: pt_fresh_left_ineq[OF pta, OF ptb, OF at, OF cp])
-apply(drule_tac x="pi\<bullet>xa" in bspec)
-apply(simp add: pt_set_bij1[OF ptb, OF at])
-apply(simp add: pt_set_eqvt [OF ptb at] pt_rev_pi[OF pt_list_inst[OF ptb], OF at])
-apply(simp add: pt_fresh_bij_ineq[OF pta, OF ptb, OF at, OF cp])
-apply(drule_tac x="(rev pi)\<bullet>xa" in bspec)
-apply(simp add: pt_set_bij1[OF ptb, OF at] pt_set_eqvt [OF ptb at])
-apply(simp add: pt_fresh_left_ineq[OF pta, OF ptb, OF at, OF cp])
-done
-
lemma pt_fresh_left:
fixes pi :: "'x prm"
and x :: "'a"
@@ -1651,56 +1592,6 @@
apply(rule at)
done
-lemma pt_fresh_star_bij:
- fixes pi :: "'x prm"
- and x :: "'a"
- and a :: "'x set"
- and b :: "'x list"
- assumes pt: "pt TYPE('a) TYPE('x)"
- and at: "at TYPE('x)"
- shows "(pi\<bullet>a)\<sharp>*(pi\<bullet>x) = a\<sharp>*x"
- and "(pi\<bullet>b)\<sharp>*(pi\<bullet>x) = b\<sharp>*x"
-apply(rule pt_fresh_star_bij_ineq(1))
-apply(rule pt)
-apply(rule at_pt_inst)
-apply(rule at)+
-apply(rule cp_pt_inst)
-apply(rule pt)
-apply(rule at)
-apply(rule pt_fresh_star_bij_ineq(2))
-apply(rule pt)
-apply(rule at_pt_inst)
-apply(rule at)+
-apply(rule cp_pt_inst)
-apply(rule pt)
-apply(rule at)
-done
-
-lemma pt_fresh_star_eqvt:
- fixes pi :: "'x prm"
- and x :: "'a"
- and a :: "'x set"
- and b :: "'x list"
- assumes pt: "pt TYPE('a) TYPE('x)"
- and at: "at TYPE('x)"
- shows "pi\<bullet>(a\<sharp>*x) = (pi\<bullet>a)\<sharp>*(pi\<bullet>x)"
- and "pi\<bullet>(b\<sharp>*x) = (pi\<bullet>b)\<sharp>*(pi\<bullet>x)"
- by (simp_all add: perm_bool pt_fresh_star_bij[OF pt, OF at])
-
-lemma pt_fresh_star_eqvt_ineq:
- fixes pi::"'x prm"
- and a::"'y set"
- and b::"'y list"
- and x::"'a"
- assumes pta: "pt TYPE('a) TYPE('x)"
- and ptb: "pt TYPE('y) TYPE('x)"
- and at: "at TYPE('x)"
- and cp: "cp TYPE('a) TYPE('x) TYPE('y)"
- and dj: "disjoint TYPE('y) TYPE('x)"
- shows "pi\<bullet>(a\<sharp>*x) = (pi\<bullet>a)\<sharp>*(pi\<bullet>x)"
- and "pi\<bullet>(b\<sharp>*x) = (pi\<bullet>b)\<sharp>*(pi\<bullet>x)"
- by (simp_all add: pt_fresh_star_bij_ineq[OF pta, OF ptb, OF at, OF cp] dj_perm_forget[OF dj] perm_bool)
-
lemma pt_fresh_bij1:
fixes pi :: "'x prm"
and x :: "'a"
@@ -1753,7 +1644,6 @@
(* the next two lemmas are needed in the proof *)
(* of the structural induction principle *)
-
lemma pt_fresh_aux:
fixes a::"'x"
and b::"'x"
@@ -1857,27 +1747,6 @@
thus ?thesis using eq3 by simp
qed
-lemma pt_freshs_freshs:
- assumes pt: "pt TYPE('a) TYPE('x)"
- and at: "at TYPE ('x)"
- and pi: "set (pi::'x prm) \<subseteq> Xs \<times> Ys"
- and Xs: "Xs \<sharp>* (x::'a)"
- and Ys: "Ys \<sharp>* x"
- shows "pi \<bullet> x = x"
- using pi
-proof (induct pi)
- case Nil
- show ?case by (simp add: pt1 [OF pt])
-next
- case (Cons p pi)
- obtain a b where p: "p = (a, b)" by (cases p)
- with Cons Xs Ys have "a \<sharp> x" "b \<sharp> x"
- by (simp_all add: fresh_star_def)
- with Cons p show ?case
- by (simp add: pt_fresh_fresh [OF pt at]
- pt2 [OF pt, of "[(a, b)]" pi, simplified])
-qed
-
lemma pt_pi_fresh_fresh:
fixes x :: "'a"
and pi :: "'x prm"
@@ -1943,8 +1812,7 @@
thus ?thesis by (simp add: pt2[OF pt])
qed
-section {* equivaraince for some connectives *}
-
+section {* equivariance for some connectives *}
lemma pt_all_eqvt:
fixes pi :: "'x prm"
and x :: "'a"
@@ -1990,8 +1858,6 @@
apply(rule theI'[OF unique])
done
-
-
section {* facts about supports *}
(*==============================*)
@@ -2160,6 +2026,7 @@
shows "(x \<sharp> X) = (x \<notin> X)"
by (simp add: at_fin_set_supp fresh_def at fs)
+
section {* Permutations acting on Functions *}
(*==========================================*)
@@ -2540,9 +2407,8 @@
and a1: "a\<sharp>x"
and a2: "a\<sharp>X"
shows "a\<sharp>(insert x X)"
-using a1 a2
-apply(simp add: fresh_fin_insert[OF pt, OF at, OF fs, OF f])
-done
+ using a1 a2
+ by (simp add: fresh_fin_insert[OF pt, OF at, OF fs, OF f])
lemma pt_list_set_supp:
fixes xs :: "'a list"
@@ -2571,14 +2437,191 @@
shows "a\<sharp>(set xs) = a\<sharp>xs"
by (simp add: fresh_def pt_list_set_supp[OF pt, OF at, OF fs])
+
+section {* generalisation of freshness to lists and sets of atoms *}
+(*================================================================*)
+
+consts
+ fresh_star :: "'b \<Rightarrow> 'a \<Rightarrow> bool" ("_ \<sharp>* _" [100,100] 100)
+
+defs (overloaded)
+ fresh_star_set: "xs\<sharp>*c \<equiv> \<forall>x\<in>xs. x\<sharp>c"
+
+defs (overloaded)
+ fresh_star_list: "xs\<sharp>*c \<equiv> \<forall>x\<in>set xs. x\<sharp>c"
+
+lemmas fresh_star_def = fresh_star_list fresh_star_set
+
+lemma fresh_star_prod_set:
+ fixes xs::"'a set"
+ shows "xs\<sharp>*(a,b) = (xs\<sharp>*a \<and> xs\<sharp>*b)"
+by (auto simp add: fresh_star_def fresh_prod)
+
+lemma fresh_star_prod_list:
+ fixes xs::"'a list"
+ shows "xs\<sharp>*(a,b) = (xs\<sharp>*a \<and> xs\<sharp>*b)"
+ by (auto simp add: fresh_star_def fresh_prod)
+
+lemmas fresh_star_prod = fresh_star_prod_list fresh_star_prod_set
+
+lemma fresh_star_set_eq: "set xs \<sharp>* c = xs \<sharp>* c"
+ by (simp add: fresh_star_def)
+
+lemma fresh_star_Un_elim:
+ "((S \<union> T) \<sharp>* c \<Longrightarrow> PROP C) \<equiv> (S \<sharp>* c \<Longrightarrow> T \<sharp>* c \<Longrightarrow> PROP C)"
+ apply rule
+ apply (simp_all add: fresh_star_def)
+ apply (erule meta_mp)
+ apply blast
+ done
+
+lemma fresh_star_insert_elim:
+ "(insert x S \<sharp>* c \<Longrightarrow> PROP C) \<equiv> (x \<sharp> c \<Longrightarrow> S \<sharp>* c \<Longrightarrow> PROP C)"
+ by rule (simp_all add: fresh_star_def)
+
+lemma fresh_star_empty_elim:
+ "({} \<sharp>* c \<Longrightarrow> PROP C) \<equiv> PROP C"
+ by (simp add: fresh_star_def)
+
+text {* Normalization of freshness results; see \ @{text nominal_induct} *}
+
+lemma fresh_star_unit_elim:
+ shows "((a::'a set)\<sharp>*() \<Longrightarrow> PROP C) \<equiv> PROP C"
+ and "((b::'a list)\<sharp>*() \<Longrightarrow> PROP C) \<equiv> PROP C"
+ by (simp_all add: fresh_star_def fresh_def supp_unit)
+
+lemma fresh_star_prod_elim:
+ shows "((a::'a set)\<sharp>*(x,y) \<Longrightarrow> PROP C) \<equiv> (a\<sharp>*x \<Longrightarrow> a\<sharp>*y \<Longrightarrow> PROP C)"
+ and "((b::'a list)\<sharp>*(x,y) \<Longrightarrow> PROP C) \<equiv> (b\<sharp>*x \<Longrightarrow> b\<sharp>*y \<Longrightarrow> PROP C)"
+ by (rule, simp_all add: fresh_star_prod)+
+
+
+lemma pt_fresh_star_bij_ineq:
+ fixes pi :: "'x prm"
+ and x :: "'a"
+ and a :: "'y set"
+ and b :: "'y list"
+ assumes pta: "pt TYPE('a) TYPE('x)"
+ and ptb: "pt TYPE('y) TYPE('x)"
+ and at: "at TYPE('x)"
+ and cp: "cp TYPE('a) TYPE('x) TYPE('y)"
+ shows "(pi\<bullet>a)\<sharp>*(pi\<bullet>x) = a\<sharp>*x"
+ and "(pi\<bullet>b)\<sharp>*(pi\<bullet>x) = b\<sharp>*x"
+apply(unfold fresh_star_def)
+apply(auto)
+apply(drule_tac x="pi\<bullet>xa" in bspec)
+apply(erule pt_set_bij2[OF ptb, OF at])
+apply(simp add: fresh_star_def pt_fresh_bij_ineq[OF pta, OF ptb, OF at, OF cp])
+apply(drule_tac x="(rev pi)\<bullet>xa" in bspec)
+apply(simp add: pt_set_bij1[OF ptb, OF at])
+apply(simp add: pt_fresh_left_ineq[OF pta, OF ptb, OF at, OF cp])
+apply(drule_tac x="pi\<bullet>xa" in bspec)
+apply(simp add: pt_set_bij1[OF ptb, OF at])
+apply(simp add: pt_set_eqvt [OF ptb at] pt_rev_pi[OF pt_list_inst[OF ptb], OF at])
+apply(simp add: pt_fresh_bij_ineq[OF pta, OF ptb, OF at, OF cp])
+apply(drule_tac x="(rev pi)\<bullet>xa" in bspec)
+apply(simp add: pt_set_bij1[OF ptb, OF at] pt_set_eqvt [OF ptb at])
+apply(simp add: pt_fresh_left_ineq[OF pta, OF ptb, OF at, OF cp])
+done
+
+lemma pt_fresh_star_bij:
+ fixes pi :: "'x prm"
+ and x :: "'a"
+ and a :: "'x set"
+ and b :: "'x list"
+ assumes pt: "pt TYPE('a) TYPE('x)"
+ and at: "at TYPE('x)"
+ shows "(pi\<bullet>a)\<sharp>*(pi\<bullet>x) = a\<sharp>*x"
+ and "(pi\<bullet>b)\<sharp>*(pi\<bullet>x) = b\<sharp>*x"
+apply(rule pt_fresh_star_bij_ineq(1))
+apply(rule pt)
+apply(rule at_pt_inst)
+apply(rule at)+
+apply(rule cp_pt_inst)
+apply(rule pt)
+apply(rule at)
+apply(rule pt_fresh_star_bij_ineq(2))
+apply(rule pt)
+apply(rule at_pt_inst)
+apply(rule at)+
+apply(rule cp_pt_inst)
+apply(rule pt)
+apply(rule at)
+done
+
+lemma pt_fresh_star_eqvt:
+ fixes pi :: "'x prm"
+ and x :: "'a"
+ and a :: "'x set"
+ and b :: "'x list"
+ assumes pt: "pt TYPE('a) TYPE('x)"
+ and at: "at TYPE('x)"
+ shows "pi\<bullet>(a\<sharp>*x) = (pi\<bullet>a)\<sharp>*(pi\<bullet>x)"
+ and "pi\<bullet>(b\<sharp>*x) = (pi\<bullet>b)\<sharp>*(pi\<bullet>x)"
+ by (simp_all add: perm_bool pt_fresh_star_bij[OF pt, OF at])
+
+lemma pt_fresh_star_eqvt_ineq:
+ fixes pi::"'x prm"
+ and a::"'y set"
+ and b::"'y list"
+ and x::"'a"
+ assumes pta: "pt TYPE('a) TYPE('x)"
+ and ptb: "pt TYPE('y) TYPE('x)"
+ and at: "at TYPE('x)"
+ and cp: "cp TYPE('a) TYPE('x) TYPE('y)"
+ and dj: "disjoint TYPE('y) TYPE('x)"
+ shows "pi\<bullet>(a\<sharp>*x) = (pi\<bullet>a)\<sharp>*(pi\<bullet>x)"
+ and "pi\<bullet>(b\<sharp>*x) = (pi\<bullet>b)\<sharp>*(pi\<bullet>x)"
+ by (simp_all add: pt_fresh_star_bij_ineq[OF pta, OF ptb, OF at, OF cp] dj_perm_forget[OF dj] perm_bool)
+
+lemma pt_freshs_freshs:
+ assumes pt: "pt TYPE('a) TYPE('x)"
+ and at: "at TYPE ('x)"
+ and pi: "set (pi::'x prm) \<subseteq> Xs \<times> Ys"
+ and Xs: "Xs \<sharp>* (x::'a)"
+ and Ys: "Ys \<sharp>* x"
+ shows "pi\<bullet>x = x"
+ using pi
+proof (induct pi)
+ case Nil
+ show ?case by (simp add: pt1 [OF pt])
+next
+ case (Cons p pi)
+ obtain a b where p: "p = (a, b)" by (cases p)
+ with Cons Xs Ys have "a \<sharp> x" "b \<sharp> x"
+ by (simp_all add: fresh_star_def)
+ with Cons p show ?case
+ by (simp add: pt_fresh_fresh [OF pt at]
+ pt2 [OF pt, of "[(a, b)]" pi, simplified])
+qed
+
+lemma pt_fresh_star_pi:
+ fixes x::"'a"
+ and pi::"'x prm"
+ assumes pt: "pt TYPE('a) TYPE('x)"
+ and at: "at TYPE('x)"
+ and a: "((supp x)::'x set)\<sharp>* pi"
+ shows "pi\<bullet>x = x"
+using a
+apply(induct pi)
+apply(auto simp add: fresh_star_def fresh_list_cons fresh_prod pt1[OF pt])
+apply(subgoal_tac "((a,b)#pi)\<bullet>x = ([(a,b)]@pi)\<bullet>x")
+apply(simp only: pt2[OF pt])
+apply(rule pt_fresh_fresh[OF pt at])
+apply(simp add: fresh_def at_supp[OF at])
+apply(blast)
+apply(simp add: fresh_def at_supp[OF at])
+apply(blast)
+apply(simp add: pt2[OF pt])
+done
+
section {* Infrastructure lemmas for strong rule inductions *}
(*==========================================================*)
-
text {*
For every set of atoms, there is another set of atoms
avoiding a finitely supported c and there is a permutation
- which make 'translates' between both sets.
+ which 'translates' between both sets.
*}
lemma at_set_avoiding_aux:
fixes Xs::"'a set"
@@ -3365,7 +3408,6 @@
syntax ABS :: "type \<Rightarrow> type \<Rightarrow> type" ("\<guillemotleft>_\<guillemotright>_" [1000,1000] 1000)
-
section {* lemmas for deciding permutation equations *}
(*===================================================*)
@@ -3526,8 +3568,8 @@
shows "pi\<bullet>(x div y) = (pi\<bullet>x) div (pi\<bullet>y)"
by (simp add:perm_int_def)
-(*******************************************************************)
-(* Setup of the theorem attributes eqvt, eqvt_force, fresh and bij *)
+(*******************************************************)
+(* Setup of the theorem attributes eqvt and eqvt_force *)
use "nominal_thmdecls.ML"
setup "NominalThmDecls.setup"
--- a/src/HOL/Nominal/nominal_atoms.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Nominal/nominal_atoms.ML Mon May 11 17:20:52 2009 +0200
@@ -732,18 +732,18 @@
in
thy26
- |> discrete_pt_inst "nat" @{thm "perm_nat_def"}
- |> discrete_fs_inst "nat" @{thm "perm_nat_def"}
- |> discrete_cp_inst "nat" @{thm "perm_nat_def"}
- |> discrete_pt_inst "bool" @{thm "perm_bool"}
- |> discrete_fs_inst "bool" @{thm "perm_bool"}
- |> discrete_cp_inst "bool" @{thm "perm_bool"}
- |> discrete_pt_inst @{type_name "Int.int"} @{thm "perm_int_def"}
- |> discrete_fs_inst @{type_name "Int.int"} @{thm "perm_int_def"}
- |> discrete_cp_inst @{type_name "Int.int"} @{thm "perm_int_def"}
- |> discrete_pt_inst "List.char" @{thm "perm_char_def"}
- |> discrete_fs_inst "List.char" @{thm "perm_char_def"}
- |> discrete_cp_inst "List.char" @{thm "perm_char_def"}
+ |> discrete_pt_inst @{type_name nat} @{thm "perm_nat_def"}
+ |> discrete_fs_inst @{type_name nat} @{thm "perm_nat_def"}
+ |> discrete_cp_inst @{type_name nat} @{thm "perm_nat_def"}
+ |> discrete_pt_inst @{type_name bool} @{thm "perm_bool"}
+ |> discrete_fs_inst @{type_name bool} @{thm "perm_bool"}
+ |> discrete_cp_inst @{type_name bool} @{thm "perm_bool"}
+ |> discrete_pt_inst @{type_name int} @{thm "perm_int_def"}
+ |> discrete_fs_inst @{type_name int} @{thm "perm_int_def"}
+ |> discrete_cp_inst @{type_name int} @{thm "perm_int_def"}
+ |> discrete_pt_inst @{type_name char} @{thm "perm_char_def"}
+ |> discrete_fs_inst @{type_name char} @{thm "perm_char_def"}
+ |> discrete_cp_inst @{type_name char} @{thm "perm_char_def"}
end;
--- a/src/HOL/Nominal/nominal_thmdecls.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Nominal/nominal_thmdecls.ML Mon May 11 17:20:52 2009 +0200
@@ -1,12 +1,12 @@
(* Authors: Julien Narboux and Christian Urban
This file introduces the infrastructure for the lemma
- declaration "eqvts" "bijs" and "freshs".
+ collection "eqvts".
- By attaching [eqvt] [bij] or [fresh] to a lemma, the lemma gets stored
- in a data-slot in the context. Possible modifiers
- are [attribute add] and [attribute del] for adding and deleting,
- respectively the lemma from the data-slot.
+ By attaching [eqvt] or [eqvt_force] to a lemma, it will get
+ stored in a data-slot in the context. Possible modifiers
+ are [... add] and [... del] for adding and deleting,
+ respectively, the lemma from the data-slot.
*)
signature NOMINAL_THMDECLS =
@@ -17,9 +17,6 @@
val eqvt_force_del: attribute
val setup: theory -> theory
val get_eqvt_thms: Proof.context -> thm list
- val get_fresh_thms: Proof.context -> thm list
- val get_bij_thms: Proof.context -> thm list
-
val NOMINAL_EQVT_DEBUG : bool ref
end;
@@ -29,13 +26,11 @@
structure Data = GenericDataFun
(
- type T = {eqvts:thm list, freshs:thm list, bijs:thm list};
- val empty = ({eqvts=[], freshs=[], bijs=[]}:T);
- val extend = I;
- fun merge _ (r1:T,r2:T) = {eqvts = Thm.merge_thms (#eqvts r1, #eqvts r2),
- freshs = Thm.merge_thms (#freshs r1, #freshs r2),
- bijs = Thm.merge_thms (#bijs r1, #bijs r2)}
-);
+ type T = thm list
+ val empty = []:T
+ val extend = I
+ fun merge _ (r1:T, r2:T) = Thm.merge_thms (r1, r2)
+)
(* Exception for when a theorem does not conform with form of an equivariance lemma. *)
(* There are two forms: one is an implication (for relations) and the other is an *)
@@ -46,72 +41,68 @@
(* the implicational case it is also checked that the variables and permutation fit *)
(* together, i.e. are of the right "pt_class", so that a stronger version of the *)
(* equality-lemma can be derived. *)
-exception EQVT_FORM of string;
+exception EQVT_FORM of string
-val get_eqvt_thms = Context.Proof #> Data.get #> #eqvts;
-val get_fresh_thms = Context.Proof #> Data.get #> #freshs;
-val get_bij_thms = Context.Proof #> Data.get #> #bijs;
+val NOMINAL_EQVT_DEBUG = ref false
-(* FIXME: should be a function in a library *)
-fun mk_permT T = HOLogic.listT (HOLogic.mk_prodT (T, T));
-
-val NOMINAL_EQVT_DEBUG = ref false;
-
-fun tactic (msg,tac) =
- if !NOMINAL_EQVT_DEBUG
- then tac THEN print_tac ("after "^msg)
- else tac
+fun tactic (msg, tac) =
+ if !NOMINAL_EQVT_DEBUG
+ then tac THEN' (K (print_tac ("after " ^ msg)))
+ else tac
-fun tactic_eqvt ctx orig_thm pi pi' =
- let
- val mypi = Thm.cterm_of ctx pi
- val T = fastype_of pi'
- val mypifree = Thm.cterm_of ctx (Const ("List.rev", T --> T) $ pi')
- val perm_pi_simp = PureThy.get_thms ctx "perm_pi_simp"
- in
- EVERY [tactic ("iffI applied",rtac iffI 1),
- tactic ("remove pi with perm_boolE", (dtac @{thm perm_boolE} 1)),
- tactic ("solve with orig_thm", (etac orig_thm 1)),
- tactic ("applies orig_thm instantiated with rev pi",
- dtac (Drule.cterm_instantiate [(mypi,mypifree)] orig_thm) 1),
- tactic ("getting rid of the pi on the right",
- (rtac @{thm perm_boolI} 1)),
- tactic ("getting rid of all remaining perms",
- full_simp_tac (HOL_basic_ss addsimps perm_pi_simp) 1)]
- end;
+fun prove_eqvt_tac ctxt orig_thm pi pi' =
+let
+ val mypi = Thm.cterm_of ctxt pi
+ val T = fastype_of pi'
+ val mypifree = Thm.cterm_of ctxt (Const (@{const_name "rev"}, T --> T) $ pi')
+ val perm_pi_simp = PureThy.get_thms ctxt "perm_pi_simp"
+in
+ EVERY1 [tactic ("iffI applied", rtac @{thm iffI}),
+ tactic ("remove pi with perm_boolE", dtac @{thm perm_boolE}),
+ tactic ("solve with orig_thm", etac orig_thm),
+ tactic ("applies orig_thm instantiated with rev pi",
+ dtac (Drule.cterm_instantiate [(mypi,mypifree)] orig_thm)),
+ tactic ("getting rid of the pi on the right", rtac @{thm perm_boolI}),
+ tactic ("getting rid of all remaining perms",
+ full_simp_tac (HOL_basic_ss addsimps perm_pi_simp))]
+end;
fun get_derived_thm ctxt hyp concl orig_thm pi typi =
let
val thy = ProofContext.theory_of ctxt;
val pi' = Var (pi, typi);
- val lhs = Const ("Nominal.perm", typi --> HOLogic.boolT --> HOLogic.boolT) $ pi' $ hyp;
+ val lhs = Const (@{const_name "perm"}, typi --> HOLogic.boolT --> HOLogic.boolT) $ pi' $ hyp;
val ([goal_term, pi''], ctxt') = Variable.import_terms false
[HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, concl)), pi'] ctxt
val _ = Display.print_cterm (cterm_of thy goal_term)
in
Goal.prove ctxt' [] [] goal_term
- (fn _ => tactic_eqvt thy orig_thm pi' pi'') |>
+ (fn _ => prove_eqvt_tac thy orig_thm pi' pi'') |>
singleton (ProofContext.export ctxt' ctxt)
end
-(* replaces every variable x in t with pi o x *)
-fun apply_pi trm (pi,typi) =
- let
- fun only_vars t =
- (case t of
- Var (n,ty) => (Const ("Nominal.perm",typi --> ty --> ty) $ (Var (pi,typi)) $ (Var (n,ty)))
- | _ => t)
+(* replaces in t every variable, say x, with pi o x *)
+fun apply_pi trm (pi, typi) =
+let
+ fun replace n ty =
+ let
+ val c = Const (@{const_name "perm"}, typi --> ty --> ty)
+ val v1 = Var (pi, typi)
+ val v2 = Var (n, ty)
in
- map_aterms only_vars trm
- end;
+ c $ v1 $ v2
+ end
+in
+ map_aterms (fn Var (n, ty) => replace n ty | t => t) trm
+end
(* returns *the* pi which is in front of all variables, provided there *)
(* exists such a pi; otherwise raises EQVT_FORM *)
fun get_pi t thy =
let fun get_pi_aux s =
(case s of
- (Const ("Nominal.perm",typrm) $
- (Var (pi,typi as Type("List.list",[Type ("*",[Type (tyatm,[]),_])]))) $
+ (Const (@{const_name "perm"} ,typrm) $
+ (Var (pi,typi as Type(@{type_name "list"}, [Type ("*", [Type (tyatm,[]),_])]))) $
(Var (n,ty))) =>
let
(* FIXME: this should be an operation the library *)
@@ -130,7 +121,7 @@
(* to ensure that all pi's must have been the same, i.e. distinct returns *)
(* a singleton-list *)
(case (distinct (op =) (get_pi_aux t)) of
- [(pi,typi)] => (pi,typi)
+ [(pi,typi)] => (pi, typi)
| _ => raise EQVT_FORM "All permutation should be the same")
end;
@@ -155,8 +146,8 @@
else raise EQVT_FORM "Type Implication"
end
(* case: eqvt-lemma is of the equational form *)
- | (Const ("Trueprop", _) $ (Const ("op =", _) $
- (Const ("Nominal.perm",typrm) $ Var (pi,typi) $ lhs) $ rhs)) =>
+ | (Const (@{const_name "Trueprop"}, _) $ (Const (@{const_name "op ="}, _) $
+ (Const (@{const_name "perm"},typrm) $ Var (pi,typi) $ lhs) $ rhs)) =>
(if (apply_pi lhs (pi,typi)) = rhs
then [orig_thm]
else raise EQVT_FORM "Type Equality")
@@ -165,38 +156,24 @@
fold (fn thm => Data.map (flag thm)) thms_to_be_added context
end
handle EQVT_FORM s =>
- error (Display.string_of_thm orig_thm ^ " does not comply with the form of an equivariance lemma ("^s^").")
-
-(* in cases of bij- and freshness, we just add the lemmas to the *)
-(* data-slot *)
-
-fun eqvt_map f (r:Data.T) = {eqvts = f (#eqvts r), freshs = #freshs r, bijs = #bijs r};
-fun fresh_map f (r:Data.T) = {eqvts = #eqvts r, freshs = f (#freshs r), bijs = #bijs r};
-fun bij_map f (r:Data.T) = {eqvts = #eqvts r, freshs = #freshs r, bijs = f (#bijs r)};
-
-val eqvt_add = Thm.declaration_attribute (eqvt_add_del_aux (eqvt_map o Thm.add_thm));
-val eqvt_del = Thm.declaration_attribute (eqvt_add_del_aux (eqvt_map o Thm.del_thm));
-
-val eqvt_force_add = Thm.declaration_attribute (Data.map o eqvt_map o Thm.add_thm);
-val eqvt_force_del = Thm.declaration_attribute (Data.map o eqvt_map o Thm.del_thm);
-val bij_add = Thm.declaration_attribute (Data.map o bij_map o Thm.add_thm);
-val bij_del = Thm.declaration_attribute (Data.map o bij_map o Thm.del_thm);
-val fresh_add = Thm.declaration_attribute (Data.map o fresh_map o Thm.add_thm);
-val fresh_del = Thm.declaration_attribute (Data.map o fresh_map o Thm.del_thm);
+ error (Display.string_of_thm orig_thm ^
+ " does not comply with the form of an equivariance lemma (" ^ s ^").")
+val eqvt_add = Thm.declaration_attribute (eqvt_add_del_aux (Thm.add_thm));
+val eqvt_del = Thm.declaration_attribute (eqvt_add_del_aux (Thm.del_thm));
+
+val eqvt_force_add = Thm.declaration_attribute (Data.map o Thm.add_thm);
+val eqvt_force_del = Thm.declaration_attribute (Data.map o Thm.del_thm);
+
+val get_eqvt_thms = Context.Proof #> Data.get;
val setup =
- Attrib.setup @{binding eqvt} (Attrib.add_del eqvt_add eqvt_del)
- "equivariance theorem declaration" #>
- Attrib.setup @{binding eqvt_force} (Attrib.add_del eqvt_force_add eqvt_force_del)
- "equivariance theorem declaration (without checking the form of the lemma)" #>
- Attrib.setup @{binding fresh} (Attrib.add_del fresh_add fresh_del)
- "freshness theorem declaration" #>
- Attrib.setup @{binding "bij"} (Attrib.add_del bij_add bij_del)
- "bijection theorem declaration" #>
- PureThy.add_thms_dynamic (Binding.name "eqvts", #eqvts o Data.get) #>
- PureThy.add_thms_dynamic (Binding.name "freshs", #freshs o Data.get) #>
- PureThy.add_thms_dynamic (Binding.name "bijs", #bijs o Data.get);
+ Attrib.setup @{binding eqvt} (Attrib.add_del eqvt_add eqvt_del)
+ "equivariance theorem declaration"
+ #> Attrib.setup @{binding eqvt_force} (Attrib.add_del eqvt_force_add eqvt_force_del)
+ "equivariance theorem declaration (without checking the form of the lemma)"
+ #> PureThy.add_thms_dynamic (Binding.name "eqvts", Data.get)
+
end;
--- a/src/HOL/NthRoot.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/NthRoot.thy Mon May 11 17:20:52 2009 +0200
@@ -565,16 +565,6 @@
lemma le_real_sqrt_sumsq [simp]: "x \<le> sqrt (x * x + y * y)"
by (simp add: power2_eq_square [symmetric])
-lemma power2_sum:
- fixes x y :: "'a::{number_ring,recpower}"
- shows "(x + y)\<twosuperior> = x\<twosuperior> + y\<twosuperior> + 2 * x * y"
-by (simp add: ring_distribs power2_eq_square)
-
-lemma power2_diff:
- fixes x y :: "'a::{number_ring,recpower}"
- shows "(x - y)\<twosuperior> = x\<twosuperior> + y\<twosuperior> - 2 * x * y"
-by (simp add: ring_distribs power2_eq_square)
-
lemma real_sqrt_sum_squares_triangle_ineq:
"sqrt ((a + c)\<twosuperior> + (b + d)\<twosuperior>) \<le> sqrt (a\<twosuperior> + b\<twosuperior>) + sqrt (c\<twosuperior> + d\<twosuperior>)"
apply (rule power2_le_imp_le, simp)
--- a/src/HOL/Option.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Option.thy Mon May 11 17:20:52 2009 +0200
@@ -20,6 +20,9 @@
only when applied to assumptions, in practice it seems better to give
them the uniform iff attribute. *}
+lemma inj_Some [simp]: "inj_on Some A"
+by (rule inj_onI) simp
+
lemma option_caseE:
assumes c: "(case x of None => P | Some y => Q y)"
obtains
@@ -27,14 +30,15 @@
| (Some) y where "x = Some y" and "Q y"
using c by (cases x) simp_all
-lemma insert_None_conv_UNIV: "insert None (range Some) = UNIV"
- by (rule set_ext, case_tac x) auto
+lemma UNIV_option_conv: "UNIV = insert None (range Some)"
+by(auto intro: classical)
+
+lemma finite_option_UNIV[simp]:
+ "finite (UNIV :: 'a option set) = finite (UNIV :: 'a set)"
+by(auto simp add: UNIV_option_conv elim: finite_imageD intro: inj_Some)
instance option :: (finite) finite proof
-qed (simp add: insert_None_conv_UNIV [symmetric])
-
-lemma inj_Some [simp]: "inj_on Some A"
- by (rule inj_onI) simp
+qed (simp add: UNIV_option_conv)
subsubsection {* Operations *}
--- a/src/HOL/Orderings.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Orderings.thy Mon May 11 17:20:52 2009 +0200
@@ -5,7 +5,7 @@
header {* Abstract orderings *}
theory Orderings
-imports Code_Setup
+imports HOL
uses "~~/src/Provers/order.ML"
begin
--- a/src/HOL/Parity.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Parity.thy Mon May 11 17:20:52 2009 +0200
@@ -178,7 +178,7 @@
subsection {* Parity and powers *}
lemma minus_one_even_odd_power:
- "(even x --> (- 1::'a::{comm_ring_1,recpower})^x = 1) &
+ "(even x --> (- 1::'a::{comm_ring_1})^x = 1) &
(odd x --> (- 1::'a)^x = - 1)"
apply (induct x)
apply (rule conjI)
@@ -188,37 +188,37 @@
done
lemma minus_one_even_power [simp]:
- "even x ==> (- 1::'a::{comm_ring_1,recpower})^x = 1"
+ "even x ==> (- 1::'a::{comm_ring_1})^x = 1"
using minus_one_even_odd_power by blast
lemma minus_one_odd_power [simp]:
- "odd x ==> (- 1::'a::{comm_ring_1,recpower})^x = - 1"
+ "odd x ==> (- 1::'a::{comm_ring_1})^x = - 1"
using minus_one_even_odd_power by blast
lemma neg_one_even_odd_power:
- "(even x --> (-1::'a::{number_ring,recpower})^x = 1) &
+ "(even x --> (-1::'a::{number_ring})^x = 1) &
(odd x --> (-1::'a)^x = -1)"
apply (induct x)
apply (simp, simp add: power_Suc)
done
lemma neg_one_even_power [simp]:
- "even x ==> (-1::'a::{number_ring,recpower})^x = 1"
+ "even x ==> (-1::'a::{number_ring})^x = 1"
using neg_one_even_odd_power by blast
lemma neg_one_odd_power [simp]:
- "odd x ==> (-1::'a::{number_ring,recpower})^x = -1"
+ "odd x ==> (-1::'a::{number_ring})^x = -1"
using neg_one_even_odd_power by blast
lemma neg_power_if:
- "(-x::'a::{comm_ring_1,recpower}) ^ n =
+ "(-x::'a::{comm_ring_1}) ^ n =
(if even n then (x ^ n) else -(x ^ n))"
apply (induct n)
apply (simp_all split: split_if_asm add: power_Suc)
done
lemma zero_le_even_power: "even n ==>
- 0 <= (x::'a::{recpower,ordered_ring_strict}) ^ n"
+ 0 <= (x::'a::{ordered_ring_strict,monoid_mult}) ^ n"
apply (simp add: even_nat_equiv_def2)
apply (erule exE)
apply (erule ssubst)
@@ -227,12 +227,12 @@
done
lemma zero_le_odd_power: "odd n ==>
- (0 <= (x::'a::{recpower,ordered_idom}) ^ n) = (0 <= x)"
+ (0 <= (x::'a::{ordered_idom}) ^ n) = (0 <= x)"
apply (auto simp: odd_nat_equiv_def2 power_Suc power_add zero_le_mult_iff)
apply (metis field_power_not_zero no_zero_divirors_neq0 order_antisym_conv zero_le_square)
done
-lemma zero_le_power_eq[presburger]: "(0 <= (x::'a::{recpower,ordered_idom}) ^ n) =
+lemma zero_le_power_eq[presburger]: "(0 <= (x::'a::{ordered_idom}) ^ n) =
(even n | (odd n & 0 <= x))"
apply auto
apply (subst zero_le_odd_power [symmetric])
@@ -240,19 +240,19 @@
apply (erule zero_le_even_power)
done
-lemma zero_less_power_eq[presburger]: "(0 < (x::'a::{recpower,ordered_idom}) ^ n) =
+lemma zero_less_power_eq[presburger]: "(0 < (x::'a::{ordered_idom}) ^ n) =
(n = 0 | (even n & x ~= 0) | (odd n & 0 < x))"
unfolding order_less_le zero_le_power_eq by auto
-lemma power_less_zero_eq[presburger]: "((x::'a::{recpower,ordered_idom}) ^ n < 0) =
+lemma power_less_zero_eq[presburger]: "((x::'a::{ordered_idom}) ^ n < 0) =
(odd n & x < 0)"
apply (subst linorder_not_le [symmetric])+
apply (subst zero_le_power_eq)
apply auto
done
-lemma power_le_zero_eq[presburger]: "((x::'a::{recpower,ordered_idom}) ^ n <= 0) =
+lemma power_le_zero_eq[presburger]: "((x::'a::{ordered_idom}) ^ n <= 0) =
(n ~= 0 & ((odd n & x <= 0) | (even n & x = 0)))"
apply (subst linorder_not_less [symmetric])+
apply (subst zero_less_power_eq)
@@ -260,7 +260,7 @@
done
lemma power_even_abs: "even n ==>
- (abs (x::'a::{recpower,ordered_idom}))^n = x^n"
+ (abs (x::'a::{ordered_idom}))^n = x^n"
apply (subst power_abs [symmetric])
apply (simp add: zero_le_even_power)
done
@@ -269,18 +269,18 @@
by (induct n) auto
lemma power_minus_even [simp]: "even n ==>
- (- x)^n = (x^n::'a::{recpower,comm_ring_1})"
+ (- x)^n = (x^n::'a::{comm_ring_1})"
apply (subst power_minus)
apply simp
done
lemma power_minus_odd [simp]: "odd n ==>
- (- x)^n = - (x^n::'a::{recpower,comm_ring_1})"
+ (- x)^n = - (x^n::'a::{comm_ring_1})"
apply (subst power_minus)
apply simp
done
-lemma power_mono_even: fixes x y :: "'a :: {recpower, ordered_idom}"
+lemma power_mono_even: fixes x y :: "'a :: {ordered_idom}"
assumes "even n" and "\<bar>x\<bar> \<le> \<bar>y\<bar>"
shows "x^n \<le> y^n"
proof -
@@ -292,7 +292,7 @@
lemma odd_pos: "odd (n::nat) \<Longrightarrow> 0 < n" by presburger
-lemma power_mono_odd: fixes x y :: "'a :: {recpower, ordered_idom}"
+lemma power_mono_odd: fixes x y :: "'a :: {ordered_idom}"
assumes "odd n" and "x \<le> y"
shows "x^n \<le> y^n"
proof (cases "y < 0")
@@ -406,11 +406,11 @@
subsection {* An Equivalence for @{term [source] "0 \<le> a^n"} *}
lemma even_power_le_0_imp_0:
- "a ^ (2*k) \<le> (0::'a::{ordered_idom,recpower}) ==> a=0"
+ "a ^ (2*k) \<le> (0::'a::{ordered_idom}) ==> a=0"
by (induct k) (auto simp add: zero_le_mult_iff mult_le_0_iff power_Suc)
lemma zero_le_power_iff[presburger]:
- "(0 \<le> a^n) = (0 \<le> (a::'a::{ordered_idom,recpower}) | even n)"
+ "(0 \<le> a^n) = (0 \<le> (a::'a::{ordered_idom}) | even n)"
proof cases
assume even: "even n"
then obtain k where "n = 2*k"
--- a/src/HOL/Power.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Power.thy Mon May 11 17:20:52 2009 +0200
@@ -1,95 +1,179 @@
(* Title: HOL/Power.thy
- ID: $Id$
Author: Lawrence C Paulson, Cambridge University Computer Laboratory
Copyright 1997 University of Cambridge
-
*)
-header{*Exponentiation*}
+header {* Exponentiation *}
theory Power
imports Nat
begin
-class power =
- fixes power :: "'a \<Rightarrow> nat \<Rightarrow> 'a" (infixr "^" 80)
+subsection {* Powers for Arbitrary Monoids *}
+
+class power = one + times
+begin
-subsection{*Powers for Arbitrary Monoids*}
+primrec power :: "'a \<Rightarrow> nat \<Rightarrow> 'a" (infixr "^" 80) where
+ power_0: "a ^ 0 = 1"
+ | power_Suc: "a ^ Suc n = a * a ^ n"
+
+notation (latex output)
+ power ("(_\<^bsup>_\<^esup>)" [1000] 1000)
-class recpower = monoid_mult + power +
- assumes power_0 [simp]: "a ^ 0 = 1"
- assumes power_Suc [simp]: "a ^ Suc n = a * (a ^ n)"
+notation (HTML output)
+ power ("(_\<^bsup>_\<^esup>)" [1000] 1000)
+
+end
+
+context monoid_mult
+begin
-lemma power_0_Suc [simp]: "(0::'a::{recpower,semiring_0}) ^ (Suc n) = 0"
+subclass power ..
+
+lemma power_one [simp]:
+ "1 ^ n = 1"
+ by (induct n) simp_all
+
+lemma power_one_right [simp]:
+ "a ^ 1 = a"
by simp
-text{*It looks plausible as a simprule, but its effect can be strange.*}
-lemma power_0_left: "0^n = (if n=0 then 1 else (0::'a::{recpower,semiring_0}))"
- by (induct n) simp_all
-
-lemma power_one [simp]: "1^n = (1::'a::recpower)"
- by (induct n) simp_all
-
-lemma power_one_right [simp]: "(a::'a::recpower) ^ 1 = a"
- unfolding One_nat_def by simp
-
-lemma power_commutes: "(a::'a::recpower) ^ n * a = a * a ^ n"
+lemma power_commutes:
+ "a ^ n * a = a * a ^ n"
by (induct n) (simp_all add: mult_assoc)
-lemma power_Suc2: "(a::'a::recpower) ^ Suc n = a ^ n * a"
+lemma power_Suc2:
+ "a ^ Suc n = a ^ n * a"
by (simp add: power_commutes)
-lemma power_add: "(a::'a::recpower) ^ (m+n) = (a^m) * (a^n)"
- by (induct m) (simp_all add: mult_ac)
+lemma power_add:
+ "a ^ (m + n) = a ^ m * a ^ n"
+ by (induct m) (simp_all add: algebra_simps)
-lemma power_mult: "(a::'a::recpower) ^ (m*n) = (a^m) ^ n"
+lemma power_mult:
+ "a ^ (m * n) = (a ^ m) ^ n"
by (induct n) (simp_all add: power_add)
-lemma power_mult_distrib: "((a::'a::{recpower,comm_monoid_mult}) * b) ^ n = (a^n) * (b^n)"
+end
+
+context comm_monoid_mult
+begin
+
+lemma power_mult_distrib:
+ "(a * b) ^ n = (a ^ n) * (b ^ n)"
by (induct n) (simp_all add: mult_ac)
-lemma zero_less_power[simp]:
- "0 < (a::'a::{ordered_semidom,recpower}) ==> 0 < a^n"
-by (induct n) (simp_all add: mult_pos_pos)
+end
+
+context semiring_1
+begin
+
+lemma of_nat_power:
+ "of_nat (m ^ n) = of_nat m ^ n"
+ by (induct n) (simp_all add: of_nat_mult)
+
+end
+
+context comm_semiring_1
+begin
+
+text {* The divides relation *}
+
+lemma le_imp_power_dvd:
+ assumes "m \<le> n" shows "a ^ m dvd a ^ n"
+proof
+ have "a ^ n = a ^ (m + (n - m))"
+ using `m \<le> n` by simp
+ also have "\<dots> = a ^ m * a ^ (n - m)"
+ by (rule power_add)
+ finally show "a ^ n = a ^ m * a ^ (n - m)" .
+qed
+
+lemma power_le_dvd:
+ "a ^ n dvd b \<Longrightarrow> m \<le> n \<Longrightarrow> a ^ m dvd b"
+ by (rule dvd_trans [OF le_imp_power_dvd])
+
+lemma dvd_power_same:
+ "x dvd y \<Longrightarrow> x ^ n dvd y ^ n"
+ by (induct n) (auto simp add: mult_dvd_mono)
+
+lemma dvd_power_le:
+ "x dvd y \<Longrightarrow> m \<ge> n \<Longrightarrow> x ^ n dvd y ^ m"
+ by (rule power_le_dvd [OF dvd_power_same])
-lemma zero_le_power[simp]:
- "0 \<le> (a::'a::{ordered_semidom,recpower}) ==> 0 \<le> a^n"
-by (induct n) (simp_all add: mult_nonneg_nonneg)
+lemma dvd_power [simp]:
+ assumes "n > (0::nat) \<or> x = 1"
+ shows "x dvd (x ^ n)"
+using assms proof
+ assume "0 < n"
+ then have "x ^ n = x ^ Suc (n - 1)" by simp
+ then show "x dvd (x ^ n)" by simp
+next
+ assume "x = 1"
+ then show "x dvd (x ^ n)" by simp
+qed
+
+end
+
+context ring_1
+begin
+
+lemma power_minus:
+ "(- a) ^ n = (- 1) ^ n * a ^ n"
+proof (induct n)
+ case 0 show ?case by simp
+next
+ case (Suc n) then show ?case
+ by (simp del: power_Suc add: power_Suc2 mult_assoc)
+qed
+
+end
+
+context ordered_semidom
+begin
+
+lemma zero_less_power [simp]:
+ "0 < a \<Longrightarrow> 0 < a ^ n"
+ by (induct n) (simp_all add: mult_pos_pos)
+
+lemma zero_le_power [simp]:
+ "0 \<le> a \<Longrightarrow> 0 \<le> a ^ n"
+ by (induct n) (simp_all add: mult_nonneg_nonneg)
lemma one_le_power[simp]:
- "1 \<le> (a::'a::{ordered_semidom,recpower}) ==> 1 \<le> a^n"
-apply (induct "n")
-apply simp_all
-apply (rule order_trans [OF _ mult_mono [of 1 _ 1]])
-apply (simp_all add: order_trans [OF zero_le_one])
-done
-
-lemma gt1_imp_ge0: "1 < a ==> 0 \<le> (a::'a::ordered_semidom)"
- by (simp add: order_trans [OF zero_le_one order_less_imp_le])
+ "1 \<le> a \<Longrightarrow> 1 \<le> a ^ n"
+ apply (induct n)
+ apply simp_all
+ apply (rule order_trans [OF _ mult_mono [of 1 _ 1]])
+ apply (simp_all add: order_trans [OF zero_le_one])
+ done
lemma power_gt1_lemma:
- assumes gt1: "1 < (a::'a::{ordered_semidom,recpower})"
- shows "1 < a * a^n"
+ assumes gt1: "1 < a"
+ shows "1 < a * a ^ n"
proof -
- have "1*1 < a*1" using gt1 by simp
- also have "\<dots> \<le> a * a^n" using gt1
- by (simp only: mult_mono gt1_imp_ge0 one_le_power order_less_imp_le
+ from gt1 have "0 \<le> a"
+ by (fact order_trans [OF zero_le_one less_imp_le])
+ have "1 * 1 < a * 1" using gt1 by simp
+ also have "\<dots> \<le> a * a ^ n" using gt1
+ by (simp only: mult_mono `0 \<le> a` one_le_power order_less_imp_le
zero_le_one order_refl)
finally show ?thesis by simp
qed
-lemma one_less_power[simp]:
- "\<lbrakk>1 < (a::'a::{ordered_semidom,recpower}); 0 < n\<rbrakk> \<Longrightarrow> 1 < a ^ n"
-by (cases n, simp_all add: power_gt1_lemma)
+lemma power_gt1:
+ "1 < a \<Longrightarrow> 1 < a ^ Suc n"
+ by (simp add: power_gt1_lemma)
-lemma power_gt1:
- "1 < (a::'a::{ordered_semidom,recpower}) ==> 1 < a ^ (Suc n)"
-by (simp add: power_gt1_lemma)
+lemma one_less_power [simp]:
+ "1 < a \<Longrightarrow> 0 < n \<Longrightarrow> 1 < a ^ n"
+ by (cases n) (simp_all add: power_gt1_lemma)
lemma power_le_imp_le_exp:
- assumes gt1: "(1::'a::{recpower,ordered_semidom}) < a"
- shows "!!n. a^m \<le> a^n ==> m \<le> n"
-proof (induct m)
+ assumes gt1: "1 < a"
+ shows "a ^ m \<le> a ^ n \<Longrightarrow> m \<le> n"
+proof (induct m arbitrary: n)
case 0
show ?case by simp
next
@@ -97,212 +181,128 @@
show ?case
proof (cases n)
case 0
- from prems have "a * a^m \<le> 1" by simp
+ with Suc.prems Suc.hyps have "a * a ^ m \<le> 1" by simp
with gt1 show ?thesis
by (force simp only: power_gt1_lemma
- linorder_not_less [symmetric])
+ not_less [symmetric])
next
case (Suc n)
- from prems show ?thesis
+ with Suc.prems Suc.hyps show ?thesis
by (force dest: mult_left_le_imp_le
- simp add: order_less_trans [OF zero_less_one gt1])
+ simp add: less_trans [OF zero_less_one gt1])
qed
qed
text{*Surely we can strengthen this? It holds for @{text "0<a<1"} too.*}
lemma power_inject_exp [simp]:
- "1 < (a::'a::{ordered_semidom,recpower}) ==> (a^m = a^n) = (m=n)"
+ "1 < a \<Longrightarrow> a ^ m = a ^ n \<longleftrightarrow> m = n"
by (force simp add: order_antisym power_le_imp_le_exp)
text{*Can relax the first premise to @{term "0<a"} in the case of the
natural numbers.*}
lemma power_less_imp_less_exp:
- "[| (1::'a::{recpower,ordered_semidom}) < a; a^m < a^n |] ==> m < n"
-by (simp add: order_less_le [of m n] order_less_le [of "a^m" "a^n"]
- power_le_imp_le_exp)
-
+ "1 < a \<Longrightarrow> a ^ m < a ^ n \<Longrightarrow> m < n"
+ by (simp add: order_less_le [of m n] less_le [of "a^m" "a^n"]
+ power_le_imp_le_exp)
lemma power_mono:
- "[|a \<le> b; (0::'a::{recpower,ordered_semidom}) \<le> a|] ==> a^n \<le> b^n"
-apply (induct "n")
-apply simp_all
-apply (auto intro: mult_mono order_trans [of 0 a b])
-done
+ "a \<le> b \<Longrightarrow> 0 \<le> a \<Longrightarrow> a ^ n \<le> b ^ n"
+ by (induct n)
+ (auto intro: mult_mono order_trans [of 0 a b])
lemma power_strict_mono [rule_format]:
- "[|a < b; (0::'a::{recpower,ordered_semidom}) \<le> a|]
- ==> 0 < n --> a^n < b^n"
-apply (induct "n")
-apply (auto simp add: mult_strict_mono order_le_less_trans [of 0 a b])
-done
-
-lemma power_eq_0_iff [simp]:
- "(a^n = 0) \<longleftrightarrow>
- (a = (0::'a::{mult_zero,zero_neq_one,no_zero_divisors,recpower}) & n\<noteq>0)"
-apply (induct "n")
-apply (auto simp add: no_zero_divisors)
-done
-
-
-lemma field_power_not_zero:
- "a \<noteq> (0::'a::{ring_1_no_zero_divisors,recpower}) ==> a^n \<noteq> 0"
-by force
-
-lemma nonzero_power_inverse:
- fixes a :: "'a::{division_ring,recpower}"
- shows "a \<noteq> 0 ==> inverse (a ^ n) = (inverse a) ^ n"
-apply (induct "n")
-apply (auto simp add: nonzero_inverse_mult_distrib power_commutes)
-done (* TODO: reorient or rename to nonzero_inverse_power *)
-
-text{*Perhaps these should be simprules.*}
-lemma power_inverse:
- fixes a :: "'a::{division_ring,division_by_zero,recpower}"
- shows "inverse (a ^ n) = (inverse a) ^ n"
-apply (cases "a = 0")
-apply (simp add: power_0_left)
-apply (simp add: nonzero_power_inverse)
-done (* TODO: reorient or rename to inverse_power *)
-
-lemma power_one_over: "1 / (a::'a::{field,division_by_zero,recpower})^n =
- (1 / a)^n"
-apply (simp add: divide_inverse)
-apply (rule power_inverse)
-done
-
-lemma nonzero_power_divide:
- "b \<noteq> 0 ==> (a/b) ^ n = ((a::'a::{field,recpower}) ^ n) / (b ^ n)"
-by (simp add: divide_inverse power_mult_distrib nonzero_power_inverse)
-
-lemma power_divide:
- "(a/b) ^ n = ((a::'a::{field,division_by_zero,recpower}) ^ n / b ^ n)"
-apply (case_tac "b=0", simp add: power_0_left)
-apply (rule nonzero_power_divide)
-apply assumption
-done
-
-lemma power_abs: "abs(a ^ n) = abs(a::'a::{ordered_idom,recpower}) ^ n"
-apply (induct "n")
-apply (auto simp add: abs_mult)
-done
-
-lemma abs_power_minus [simp]:
- fixes a:: "'a::{ordered_idom,recpower}" shows "abs((-a) ^ n) = abs(a ^ n)"
- by (simp add: abs_minus_cancel power_abs)
-
-lemma zero_less_power_abs_iff [simp,noatp]:
- "(0 < (abs a)^n) = (a \<noteq> (0::'a::{ordered_idom,recpower}) | n=0)"
-proof (induct "n")
- case 0
- show ?case by simp
-next
- case (Suc n)
- show ?case by (auto simp add: prems zero_less_mult_iff)
-qed
-
-lemma zero_le_power_abs [simp]:
- "(0::'a::{ordered_idom,recpower}) \<le> (abs a)^n"
-by (rule zero_le_power [OF abs_ge_zero])
-
-lemma power_minus: "(-a) ^ n = (- 1)^n * (a::'a::{ring_1,recpower}) ^ n"
-proof (induct n)
- case 0 show ?case by simp
-next
- case (Suc n) then show ?case
- by (simp del: power_Suc add: power_Suc2 mult_assoc)
-qed
+ "a < b \<Longrightarrow> 0 \<le> a \<Longrightarrow> 0 < n \<longrightarrow> a ^ n < b ^ n"
+ by (induct n)
+ (auto simp add: mult_strict_mono le_less_trans [of 0 a b])
text{*Lemma for @{text power_strict_decreasing}*}
lemma power_Suc_less:
- "[|(0::'a::{ordered_semidom,recpower}) < a; a < 1|]
- ==> a * a^n < a^n"
-apply (induct n)
-apply (auto simp add: mult_strict_left_mono)
-done
+ "0 < a \<Longrightarrow> a < 1 \<Longrightarrow> a * a ^ n < a ^ n"
+ by (induct n)
+ (auto simp add: mult_strict_left_mono)
-lemma power_strict_decreasing:
- "[|n < N; 0 < a; a < (1::'a::{ordered_semidom,recpower})|]
- ==> a^N < a^n"
-apply (erule rev_mp)
-apply (induct "N")
-apply (auto simp add: power_Suc_less less_Suc_eq)
-apply (rename_tac m)
-apply (subgoal_tac "a * a^m < 1 * a^n", simp)
-apply (rule mult_strict_mono)
-apply (auto simp add: order_less_imp_le)
-done
+lemma power_strict_decreasing [rule_format]:
+ "n < N \<Longrightarrow> 0 < a \<Longrightarrow> a < 1 \<longrightarrow> a ^ N < a ^ n"
+proof (induct N)
+ case 0 then show ?case by simp
+next
+ case (Suc N) then show ?case
+ apply (auto simp add: power_Suc_less less_Suc_eq)
+ apply (subgoal_tac "a * a^N < 1 * a^n")
+ apply simp
+ apply (rule mult_strict_mono) apply auto
+ done
+qed
text{*Proof resembles that of @{text power_strict_decreasing}*}
-lemma power_decreasing:
- "[|n \<le> N; 0 \<le> a; a \<le> (1::'a::{ordered_semidom,recpower})|]
- ==> a^N \<le> a^n"
-apply (erule rev_mp)
-apply (induct "N")
-apply (auto simp add: le_Suc_eq)
-apply (rename_tac m)
-apply (subgoal_tac "a * a^m \<le> 1 * a^n", simp)
-apply (rule mult_mono)
-apply auto
-done
+lemma power_decreasing [rule_format]:
+ "n \<le> N \<Longrightarrow> 0 \<le> a \<Longrightarrow> a \<le> 1 \<longrightarrow> a ^ N \<le> a ^ n"
+proof (induct N)
+ case 0 then show ?case by simp
+next
+ case (Suc N) then show ?case
+ apply (auto simp add: le_Suc_eq)
+ apply (subgoal_tac "a * a^N \<le> 1 * a^n", simp)
+ apply (rule mult_mono) apply auto
+ done
+qed
lemma power_Suc_less_one:
- "[| 0 < a; a < (1::'a::{ordered_semidom,recpower}) |] ==> a ^ Suc n < 1"
-apply (insert power_strict_decreasing [of 0 "Suc n" a], simp)
-done
+ "0 < a \<Longrightarrow> a < 1 \<Longrightarrow> a ^ Suc n < 1"
+ using power_strict_decreasing [of 0 "Suc n" a] by simp
text{*Proof again resembles that of @{text power_strict_decreasing}*}
-lemma power_increasing:
- "[|n \<le> N; (1::'a::{ordered_semidom,recpower}) \<le> a|] ==> a^n \<le> a^N"
-apply (erule rev_mp)
-apply (induct "N")
-apply (auto simp add: le_Suc_eq)
-apply (rename_tac m)
-apply (subgoal_tac "1 * a^n \<le> a * a^m", simp)
-apply (rule mult_mono)
-apply (auto simp add: order_trans [OF zero_le_one])
-done
+lemma power_increasing [rule_format]:
+ "n \<le> N \<Longrightarrow> 1 \<le> a \<Longrightarrow> a ^ n \<le> a ^ N"
+proof (induct N)
+ case 0 then show ?case by simp
+next
+ case (Suc N) then show ?case
+ apply (auto simp add: le_Suc_eq)
+ apply (subgoal_tac "1 * a^n \<le> a * a^N", simp)
+ apply (rule mult_mono) apply (auto simp add: order_trans [OF zero_le_one])
+ done
+qed
text{*Lemma for @{text power_strict_increasing}*}
lemma power_less_power_Suc:
- "(1::'a::{ordered_semidom,recpower}) < a ==> a^n < a * a^n"
-apply (induct n)
-apply (auto simp add: mult_strict_left_mono order_less_trans [OF zero_less_one])
-done
+ "1 < a \<Longrightarrow> a ^ n < a * a ^ n"
+ by (induct n) (auto simp add: mult_strict_left_mono less_trans [OF zero_less_one])
-lemma power_strict_increasing:
- "[|n < N; (1::'a::{ordered_semidom,recpower}) < a|] ==> a^n < a^N"
-apply (erule rev_mp)
-apply (induct "N")
-apply (auto simp add: power_less_power_Suc less_Suc_eq)
-apply (rename_tac m)
-apply (subgoal_tac "1 * a^n < a * a^m", simp)
-apply (rule mult_strict_mono)
-apply (auto simp add: order_less_trans [OF zero_less_one] order_less_imp_le)
-done
+lemma power_strict_increasing [rule_format]:
+ "n < N \<Longrightarrow> 1 < a \<longrightarrow> a ^ n < a ^ N"
+proof (induct N)
+ case 0 then show ?case by simp
+next
+ case (Suc N) then show ?case
+ apply (auto simp add: power_less_power_Suc less_Suc_eq)
+ apply (subgoal_tac "1 * a^n < a * a^N", simp)
+ apply (rule mult_strict_mono) apply (auto simp add: less_trans [OF zero_less_one] less_imp_le)
+ done
+qed
lemma power_increasing_iff [simp]:
- "1 < (b::'a::{ordered_semidom,recpower}) ==> (b ^ x \<le> b ^ y) = (x \<le> y)"
-by (blast intro: power_le_imp_le_exp power_increasing order_less_imp_le)
+ "1 < b \<Longrightarrow> b ^ x \<le> b ^ y \<longleftrightarrow> x \<le> y"
+ by (blast intro: power_le_imp_le_exp power_increasing less_imp_le)
lemma power_strict_increasing_iff [simp]:
- "1 < (b::'a::{ordered_semidom,recpower}) ==> (b ^ x < b ^ y) = (x < y)"
+ "1 < b \<Longrightarrow> b ^ x < b ^ y \<longleftrightarrow> x < y"
by (blast intro: power_less_imp_less_exp power_strict_increasing)
lemma power_le_imp_le_base:
-assumes le: "a ^ Suc n \<le> b ^ Suc n"
- and ynonneg: "(0::'a::{ordered_semidom,recpower}) \<le> b"
-shows "a \<le> b"
+ assumes le: "a ^ Suc n \<le> b ^ Suc n"
+ and ynonneg: "0 \<le> b"
+ shows "a \<le> b"
proof (rule ccontr)
assume "~ a \<le> b"
then have "b < a" by (simp only: linorder_not_le)
then have "b ^ Suc n < a ^ Suc n"
by (simp only: prems power_strict_mono)
- from le and this show "False"
+ from le and this show False
by (simp add: linorder_not_less [symmetric])
qed
lemma power_less_imp_less_base:
- fixes a b :: "'a::{ordered_semidom,recpower}"
assumes less: "a ^ n < b ^ n"
assumes nonneg: "0 \<le> b"
shows "a < b"
@@ -310,98 +310,140 @@
assume "~ a < b"
hence "b \<le> a" by (simp only: linorder_not_less)
hence "b ^ n \<le> a ^ n" using nonneg by (rule power_mono)
- thus "~ a ^ n < b ^ n" by (simp only: linorder_not_less)
+ thus "\<not> a ^ n < b ^ n" by (simp only: linorder_not_less)
qed
lemma power_inject_base:
- "[| a ^ Suc n = b ^ Suc n; 0 \<le> a; 0 \<le> b |]
- ==> a = (b::'a::{ordered_semidom,recpower})"
-by (blast intro: power_le_imp_le_base order_antisym order_eq_refl sym)
+ "a ^ Suc n = b ^ Suc n \<Longrightarrow> 0 \<le> a \<Longrightarrow> 0 \<le> b \<Longrightarrow> a = b"
+by (blast intro: power_le_imp_le_base antisym eq_refl sym)
lemma power_eq_imp_eq_base:
- fixes a b :: "'a::{ordered_semidom,recpower}"
- shows "\<lbrakk>a ^ n = b ^ n; 0 \<le> a; 0 \<le> b; 0 < n\<rbrakk> \<Longrightarrow> a = b"
-by (cases n, simp_all del: power_Suc, rule power_inject_base)
+ "a ^ n = b ^ n \<Longrightarrow> 0 \<le> a \<Longrightarrow> 0 \<le> b \<Longrightarrow> 0 < n \<Longrightarrow> a = b"
+ by (cases n) (simp_all del: power_Suc, rule power_inject_base)
-text {* The divides relation *}
+end
+
+context ordered_idom
+begin
-lemma le_imp_power_dvd:
- fixes a :: "'a::{comm_semiring_1,recpower}"
- assumes "m \<le> n" shows "a^m dvd a^n"
-proof
- have "a^n = a^(m + (n - m))"
- using `m \<le> n` by simp
- also have "\<dots> = a^m * a^(n - m)"
- by (rule power_add)
- finally show "a^n = a^m * a^(n - m)" .
+lemma power_abs:
+ "abs (a ^ n) = abs a ^ n"
+ by (induct n) (auto simp add: abs_mult)
+
+lemma abs_power_minus [simp]:
+ "abs ((-a) ^ n) = abs (a ^ n)"
+ by (simp add: abs_minus_cancel power_abs)
+
+lemma zero_less_power_abs_iff [simp, noatp]:
+ "0 < abs a ^ n \<longleftrightarrow> a \<noteq> 0 \<or> n = 0"
+proof (induct n)
+ case 0 show ?case by simp
+next
+ case (Suc n) show ?case by (auto simp add: Suc zero_less_mult_iff)
qed
-lemma power_le_dvd:
- fixes a b :: "'a::{comm_semiring_1,recpower}"
- shows "a^n dvd b \<Longrightarrow> m \<le> n \<Longrightarrow> a^m dvd b"
- by (rule dvd_trans [OF le_imp_power_dvd])
+lemma zero_le_power_abs [simp]:
+ "0 \<le> abs a ^ n"
+ by (rule zero_le_power [OF abs_ge_zero])
+
+end
+
+context ring_1_no_zero_divisors
+begin
+
+lemma field_power_not_zero:
+ "a \<noteq> 0 \<Longrightarrow> a ^ n \<noteq> 0"
+ by (induct n) auto
+
+end
+context division_ring
+begin
-lemma dvd_power_same:
- "(x::'a::{comm_semiring_1,recpower}) dvd y \<Longrightarrow> x^n dvd y^n"
-by (induct n) (auto simp add: mult_dvd_mono)
+text {* FIXME reorient or rename to @{text nonzero_inverse_power} *}
+lemma nonzero_power_inverse:
+ "a \<noteq> 0 \<Longrightarrow> inverse (a ^ n) = (inverse a) ^ n"
+ by (induct n)
+ (simp_all add: nonzero_inverse_mult_distrib power_commutes field_power_not_zero)
+
+end
+
+context field
+begin
+
+lemma nonzero_power_divide:
+ "b \<noteq> 0 \<Longrightarrow> (a / b) ^ n = a ^ n / b ^ n"
+ by (simp add: divide_inverse power_mult_distrib nonzero_power_inverse)
+
+end
-lemma dvd_power_le:
- "(x::'a::{comm_semiring_1,recpower}) dvd y \<Longrightarrow> m >= n \<Longrightarrow> x^n dvd y^m"
-by(rule power_le_dvd[OF dvd_power_same])
+lemma power_0_Suc [simp]:
+ "(0::'a::{power, semiring_0}) ^ Suc n = 0"
+ by simp
+
+text{*It looks plausible as a simprule, but its effect can be strange.*}
+lemma power_0_left:
+ "0 ^ n = (if n = 0 then 1 else (0::'a::{power, semiring_0}))"
+ by (induct n) simp_all
+
+lemma power_eq_0_iff [simp]:
+ "a ^ n = 0 \<longleftrightarrow>
+ a = (0::'a::{mult_zero,zero_neq_one,no_zero_divisors,power}) \<and> n \<noteq> 0"
+ by (induct n)
+ (auto simp add: no_zero_divisors elim: contrapos_pp)
-lemma dvd_power [simp]:
- "n > 0 | (x::'a::{comm_semiring_1,recpower}) = 1 \<Longrightarrow> x dvd x^n"
-apply (erule disjE)
- apply (subgoal_tac "x ^ n = x^(Suc (n - 1))")
- apply (erule ssubst)
- apply (subst power_Suc)
- apply auto
+lemma power_diff:
+ fixes a :: "'a::field"
+ assumes nz: "a \<noteq> 0"
+ shows "n \<le> m \<Longrightarrow> a ^ (m - n) = a ^ m / a ^ n"
+ by (induct m n rule: diff_induct) (simp_all add: nz)
+
+text{*Perhaps these should be simprules.*}
+lemma power_inverse:
+ fixes a :: "'a::{division_ring,division_by_zero,power}"
+ shows "inverse (a ^ n) = (inverse a) ^ n"
+apply (cases "a = 0")
+apply (simp add: power_0_left)
+apply (simp add: nonzero_power_inverse)
+done (* TODO: reorient or rename to inverse_power *)
+
+lemma power_one_over:
+ "1 / (a::'a::{field,division_by_zero, power}) ^ n = (1 / a) ^ n"
+ by (simp add: divide_inverse) (rule power_inverse)
+
+lemma power_divide:
+ "(a / b) ^ n = (a::'a::{field,division_by_zero}) ^ n / b ^ n"
+apply (cases "b = 0")
+apply (simp add: power_0_left)
+apply (rule nonzero_power_divide)
+apply assumption
done
-subsection{*Exponentiation for the Natural Numbers*}
-
-instantiation nat :: recpower
-begin
-
-primrec power_nat where
- "p ^ 0 = (1\<Colon>nat)"
- | "p ^ (Suc n) = (p\<Colon>nat) * (p ^ n)"
+subsection {* Exponentiation for the Natural Numbers *}
-instance proof
- fix z n :: nat
- show "z^0 = 1" by simp
- show "z^(Suc n) = z * (z^n)" by simp
-qed
-
-declare power_nat.simps [simp del]
-
-end
+lemma nat_one_le_power [simp]:
+ "Suc 0 \<le> i \<Longrightarrow> Suc 0 \<le> i ^ n"
+ by (rule one_le_power [of i n, unfolded One_nat_def])
-lemma of_nat_power:
- "of_nat (m ^ n) = (of_nat m::'a::{semiring_1,recpower}) ^ n"
-by (induct n, simp_all add: of_nat_mult)
-
-lemma nat_one_le_power [simp]: "Suc 0 \<le> i ==> Suc 0 \<le> i^n"
-by (rule one_le_power [of i n, unfolded One_nat_def])
-
-lemma nat_zero_less_power_iff [simp]: "(x^n > 0) = (x > (0::nat) | n=0)"
-by (induct "n", auto)
+lemma nat_zero_less_power_iff [simp]:
+ "x ^ n > 0 \<longleftrightarrow> x > (0::nat) \<or> n = 0"
+ by (induct n) auto
lemma nat_power_eq_Suc_0_iff [simp]:
- "((x::nat)^m = Suc 0) = (m = 0 | x = Suc 0)"
-by (induct_tac m, auto)
+ "x ^ m = Suc 0 \<longleftrightarrow> m = 0 \<or> x = Suc 0"
+ by (induct m) auto
-lemma power_Suc_0[simp]: "(Suc 0)^n = Suc 0"
-by simp
+lemma power_Suc_0 [simp]:
+ "Suc 0 ^ n = Suc 0"
+ by simp
text{*Valid for the naturals, but what if @{text"0<i<1"}?
Premises cannot be weakened: consider the case where @{term "i=0"},
@{term "m=1"} and @{term "n=0"}.*}
lemma nat_power_less_imp_less:
assumes nonneg: "0 < (i\<Colon>nat)"
- assumes less: "i^m < i^n"
+ assumes less: "i ^ m < i ^ n"
shows "m < n"
proof (cases "i = 1")
case True with less power_one [where 'a = nat] show ?thesis by simp
@@ -410,10 +452,4 @@
from power_strict_increasing_iff [OF this] less show ?thesis ..
qed
-lemma power_diff:
- assumes nz: "a ~= 0"
- shows "n <= m ==> (a::'a::{recpower, field}) ^ (m-n) = (a^m) / (a^n)"
- by (induct m n rule: diff_induct)
- (simp_all add: nonzero_mult_divide_cancel_left nz)
-
end
--- a/src/HOL/Predicate.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Predicate.thy Mon May 11 17:20:52 2009 +0200
@@ -625,7 +625,56 @@
inductive eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool" where "eq x x"
lemma eq_is_eq: "eq x y \<equiv> (x = y)"
-by (rule eq_reflection) (auto intro: eq.intros elim: eq.cases)
+ by (rule eq_reflection) (auto intro: eq.intros elim: eq.cases)
+
+ML {*
+signature PREDICATE =
+sig
+ datatype 'a pred = Seq of (unit -> 'a seq)
+ and 'a seq = Empty | Insert of 'a * 'a pred | Join of 'a pred * 'a seq
+ val yield: 'a pred -> ('a * 'a pred) option
+ val yieldn: int -> 'a pred -> 'a list * 'a pred
+end;
+
+structure Predicate : PREDICATE =
+struct
+
+@{code_datatype pred = Seq};
+@{code_datatype seq = Empty | Insert | Join};
+
+fun yield (Seq f) = next (f ())
+and next @{code Empty} = NONE
+ | next (@{code Insert} (x, P)) = SOME (x, P)
+ | next (@{code Join} (P, xq)) = (case yield P
+ of NONE => next xq
+ | SOME (x, Q) => SOME (x, @{code Seq} (fn _ => @{code Join} (Q, xq))))
+
+fun anamorph f k x = (if k = 0 then ([], x)
+ else case f x
+ of NONE => ([], x)
+ | SOME (v, y) => let
+ val (vs, z) = anamorph f (k - 1) y
+ in (v :: vs, z) end)
+
+fun yieldn P = anamorph yield P;
+
+end;
+*}
+
+code_reserved Eval Predicate
+
+code_type pred and seq
+ (Eval "_/ Predicate.pred" and "_/ Predicate.seq")
+
+code_const Seq and Empty and Insert and Join
+ (Eval "Predicate.Seq" and "Predicate.Empty" and "Predicate.Insert/ (_,/ _)" and "Predicate.Join/ (_,/ _)")
+
+text {* dummy setup for code_pred keyword *}
+
+ML {*
+OuterSyntax.local_theory_to_proof "code_pred" "sets up goal for cases rule from given introduction rules and compiles predicate"
+ OuterKeyword.thy_goal (OuterParse.term_group >> (K (Proof.theorem_i NONE (K I) [[]])))
+*}
no_notation
inf (infixl "\<sqinter>" 70) and
@@ -640,12 +689,4 @@
hide (open) const Pred eval single bind if_pred not_pred
Empty Insert Join Seq member pred_of_seq "apply" adjunct eq
-text {* dummy setup for code_pred keyword *}
-
-ML {*
-OuterSyntax.local_theory_to_proof "code_pred" "sets up goal for cases rule from given introduction rules and compiles predicate"
- OuterKeyword.thy_goal (OuterParse.term_group >> (K (Proof.theorem_i NONE (K I) [[]])))
-*}
-
-
end
--- a/src/HOL/Product_Type.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Product_Type.thy Mon May 11 17:20:52 2009 +0200
@@ -84,6 +84,14 @@
lemma unit_abs_eta_conv [simp,noatp]: "(%u::unit. f ()) = f"
by (rule ext) simp
+instantiation unit :: default
+begin
+
+definition "default = ()"
+
+instance ..
+
+end
text {* code generator setup *}
--- a/src/HOL/Rational.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Rational.thy Mon May 11 17:20:52 2009 +0200
@@ -90,7 +90,7 @@
and "\<And>a c. Fract 0 a = Fract 0 c"
by (simp_all add: Fract_def)
-instantiation rat :: "{comm_ring_1, recpower}"
+instantiation rat :: comm_ring_1
begin
definition
@@ -156,11 +156,6 @@
then show ?thesis by (simp add: mult_rat [symmetric])
qed
-primrec power_rat
-where
- "q ^ 0 = (1\<Colon>rat)"
-| "q ^ Suc n = (q\<Colon>rat) * (q ^ n)"
-
instance proof
fix q r s :: rat show "(q * r) * s = q * (r * s)"
by (cases q, cases r, cases s) (simp add: eq_rat)
@@ -190,18 +185,8 @@
by (cases q, cases r, cases s) (simp add: eq_rat algebra_simps)
next
show "(0::rat) \<noteq> 1" by (simp add: Zero_rat_def One_rat_def eq_rat)
-next
- fix q :: rat show "q * 1 = q"
- by (cases q) (simp add: One_rat_def eq_rat)
-next
- fix q :: rat
- fix n :: nat
- show "q ^ 0 = 1" by simp
- show "q ^ (Suc n) = q * (q ^ n)" by simp
qed
-declare power_rat.simps [simp del]
-
end
lemma of_nat_rat: "of_nat k = Fract (of_nat k) 1"
@@ -222,7 +207,8 @@
definition
rat_number_of_def [code del]: "number_of w = Fract w 1"
-instance by intro_classes (simp add: rat_number_of_def of_int_rat)
+instance proof
+qed (simp add: rat_number_of_def of_int_rat)
end
@@ -667,7 +653,7 @@
by (cases "b = 0") (simp_all add: nonzero_of_rat_divide)
lemma of_rat_power:
- "(of_rat (a ^ n)::'a::{field_char_0,recpower}) = of_rat a ^ n"
+ "(of_rat (a ^ n)::'a::field_char_0) = of_rat a ^ n"
by (induct n) (simp_all add: of_rat_mult)
lemma of_rat_eq_iff [simp]: "(of_rat a = of_rat b) = (a = b)"
@@ -827,7 +813,7 @@
done
lemma Rats_power [simp]:
- fixes a :: "'a::{field_char_0,recpower}"
+ fixes a :: "'a::field_char_0"
shows "a \<in> Rats \<Longrightarrow> a ^ n \<in> Rats"
apply (auto simp add: Rats_def)
apply (rule range_eqI)
--- a/src/HOL/RealPow.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/RealPow.thy Mon May 11 17:20:52 2009 +0200
@@ -12,25 +12,6 @@
declare abs_mult_self [simp]
-instantiation real :: recpower
-begin
-
-primrec power_real where
- "r ^ 0 = (1\<Colon>real)"
-| "r ^ Suc n = (r\<Colon>real) * r ^ n"
-
-instance proof
- fix z :: real
- fix n :: nat
- show "z^0 = 1" by simp
- show "z^(Suc n) = z * (z^n)" by simp
-qed
-
-declare power_real.simps [simp del]
-
-end
-
-
lemma two_realpow_ge_one [simp]: "(1::real) \<le> 2 ^ n"
by simp
@@ -47,7 +28,6 @@
lemma realpow_minus_mult [rule_format]:
"0 < n --> (x::real) ^ (n - 1) * x = x ^ n"
-unfolding One_nat_def
apply (simp split add: nat_diff_split)
done
@@ -101,75 +81,6 @@
declare power_real_number_of [of _ "number_of w", standard, simp]
-subsection {* Properties of Squares *}
-
-lemma sum_squares_ge_zero:
- fixes x y :: "'a::ordered_ring_strict"
- shows "0 \<le> x * x + y * y"
-by (intro add_nonneg_nonneg zero_le_square)
-
-lemma not_sum_squares_lt_zero:
- fixes x y :: "'a::ordered_ring_strict"
- shows "\<not> x * x + y * y < 0"
-by (simp add: linorder_not_less sum_squares_ge_zero)
-
-lemma sum_nonneg_eq_zero_iff:
- fixes x y :: "'a::pordered_ab_group_add"
- assumes x: "0 \<le> x" and y: "0 \<le> y"
- shows "(x + y = 0) = (x = 0 \<and> y = 0)"
-proof (auto)
- from y have "x + 0 \<le> x + y" by (rule add_left_mono)
- also assume "x + y = 0"
- finally have "x \<le> 0" by simp
- thus "x = 0" using x by (rule order_antisym)
-next
- from x have "0 + y \<le> x + y" by (rule add_right_mono)
- also assume "x + y = 0"
- finally have "y \<le> 0" by simp
- thus "y = 0" using y by (rule order_antisym)
-qed
-
-lemma sum_squares_eq_zero_iff:
- fixes x y :: "'a::ordered_ring_strict"
- shows "(x * x + y * y = 0) = (x = 0 \<and> y = 0)"
-by (simp add: sum_nonneg_eq_zero_iff)
-
-lemma sum_squares_le_zero_iff:
- fixes x y :: "'a::ordered_ring_strict"
- shows "(x * x + y * y \<le> 0) = (x = 0 \<and> y = 0)"
-by (simp add: order_le_less not_sum_squares_lt_zero sum_squares_eq_zero_iff)
-
-lemma sum_squares_gt_zero_iff:
- fixes x y :: "'a::ordered_ring_strict"
- shows "(0 < x * x + y * y) = (x \<noteq> 0 \<or> y \<noteq> 0)"
-by (simp add: order_less_le sum_squares_ge_zero sum_squares_eq_zero_iff)
-
-lemma sum_power2_ge_zero:
- fixes x y :: "'a::{ordered_idom,recpower}"
- shows "0 \<le> x\<twosuperior> + y\<twosuperior>"
-unfolding power2_eq_square by (rule sum_squares_ge_zero)
-
-lemma not_sum_power2_lt_zero:
- fixes x y :: "'a::{ordered_idom,recpower}"
- shows "\<not> x\<twosuperior> + y\<twosuperior> < 0"
-unfolding power2_eq_square by (rule not_sum_squares_lt_zero)
-
-lemma sum_power2_eq_zero_iff:
- fixes x y :: "'a::{ordered_idom,recpower}"
- shows "(x\<twosuperior> + y\<twosuperior> = 0) = (x = 0 \<and> y = 0)"
-unfolding power2_eq_square by (rule sum_squares_eq_zero_iff)
-
-lemma sum_power2_le_zero_iff:
- fixes x y :: "'a::{ordered_idom,recpower}"
- shows "(x\<twosuperior> + y\<twosuperior> \<le> 0) = (x = 0 \<and> y = 0)"
-unfolding power2_eq_square by (rule sum_squares_le_zero_iff)
-
-lemma sum_power2_gt_zero_iff:
- fixes x y :: "'a::{ordered_idom,recpower}"
- shows "(0 < x\<twosuperior> + y\<twosuperior>) = (x \<noteq> 0 \<or> y \<noteq> 0)"
-unfolding power2_eq_square by (rule sum_squares_gt_zero_iff)
-
-
subsection{* Squares of Reals *}
lemma real_two_squares_add_zero_iff [simp]:
--- a/src/HOL/RealVector.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/RealVector.thy Mon May 11 17:20:52 2009 +0200
@@ -259,7 +259,7 @@
by (simp add: divide_inverse)
lemma of_real_power [simp]:
- "of_real (x ^ n) = (of_real x :: 'a::{real_algebra_1,recpower}) ^ n"
+ "of_real (x ^ n) = (of_real x :: 'a::{real_algebra_1}) ^ n"
by (induct n) simp_all
lemma of_real_eq_iff [simp]: "(of_real x = of_real y) = (x = y)"
@@ -389,7 +389,7 @@
done
lemma Reals_power [simp]:
- fixes a :: "'a::{real_algebra_1,recpower}"
+ fixes a :: "'a::{real_algebra_1}"
shows "a \<in> Reals \<Longrightarrow> a ^ n \<in> Reals"
apply (auto simp add: Reals_def)
apply (rule range_eqI)
@@ -613,7 +613,7 @@
by (simp add: divide_inverse norm_mult norm_inverse)
lemma norm_power_ineq:
- fixes x :: "'a::{real_normed_algebra_1,recpower}"
+ fixes x :: "'a::{real_normed_algebra_1}"
shows "norm (x ^ n) \<le> norm x ^ n"
proof (induct n)
case 0 show "norm (x ^ 0) \<le> norm x ^ 0" by simp
@@ -628,7 +628,7 @@
qed
lemma norm_power:
- fixes x :: "'a::{real_normed_div_algebra,recpower}"
+ fixes x :: "'a::{real_normed_div_algebra}"
shows "norm (x ^ n) = norm x ^ n"
by (induct n) (simp_all add: norm_mult)
--- a/src/HOL/Relation.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Relation.thy Mon May 11 17:20:52 2009 +0200
@@ -6,7 +6,8 @@
header {* Relations *}
theory Relation
-imports Datatype Finite_Set
+imports Finite_Set Datatype
+ (*FIXME order is important, otherwise merge problem for canonical interpretation of class monoid_mult wrt. power!*)
begin
subsection {* Definitions *}
--- a/src/HOL/Relation_Power.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Relation_Power.thy Mon May 11 17:20:52 2009 +0200
@@ -9,132 +9,124 @@
imports Power Transitive_Closure Plain
begin
-instance
- "fun" :: (type, type) power ..
- --{* only type @{typ "'a => 'a"} should be in class @{text power}!*}
+consts funpower :: "('a \<Rightarrow> 'b) \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> 'b" (infixr "^^" 80)
overloading
- relpow \<equiv> "power \<Colon> ('a \<times> 'a) set \<Rightarrow> nat \<Rightarrow> ('a \<times> 'a) set" (unchecked)
+ relpow \<equiv> "funpower \<Colon> ('a \<times> 'a) set \<Rightarrow> nat \<Rightarrow> ('a \<times> 'a) set"
begin
-text {* @{text "R ^ n = R O ... O R"}, the n-fold composition of @{text R} *}
+text {* @{text "R ^^ n = R O ... O R"}, the n-fold composition of @{text R} *}
primrec relpow where
- "(R \<Colon> ('a \<times> 'a) set) ^ 0 = Id"
- | "(R \<Colon> ('a \<times> 'a) set) ^ Suc n = R O (R ^ n)"
+ "(R \<Colon> ('a \<times> 'a) set) ^^ 0 = Id"
+ | "(R \<Colon> ('a \<times> 'a) set) ^^ Suc n = R O (R ^^ n)"
end
overloading
- funpow \<equiv> "power \<Colon> ('a \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> 'a" (unchecked)
+ funpow \<equiv> "funpower \<Colon> ('a \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> 'a"
begin
-text {* @{text "f ^ n = f o ... o f"}, the n-fold composition of @{text f} *}
+text {* @{text "f ^^ n = f o ... o f"}, the n-fold composition of @{text f} *}
primrec funpow where
- "(f \<Colon> 'a \<Rightarrow> 'a) ^ 0 = id"
- | "(f \<Colon> 'a \<Rightarrow> 'a) ^ Suc n = f o (f ^ n)"
+ "(f \<Colon> 'a \<Rightarrow> 'a) ^^ 0 = id"
+ | "(f \<Colon> 'a \<Rightarrow> 'a) ^^ Suc n = f o (f ^^ n)"
end
-text{*WARNING: due to the limits of Isabelle's type classes, exponentiation on
-functions and relations has too general a domain, namely @{typ "('a * 'b)set"}
-and @{typ "'a => 'b"}. Explicit type constraints may therefore be necessary.
-For example, @{term "range(f^n) = A"} and @{term "Range(R^n) = B"} need
-constraints.*}
-
-text {*
- Circumvent this problem for code generation:
-*}
-
-primrec
- fun_pow :: "nat \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a"
-where
- "fun_pow 0 f = id"
+primrec fun_pow :: "nat \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a" where
+ "fun_pow 0 f = id"
| "fun_pow (Suc n) f = f o fun_pow n f"
-lemma funpow_fun_pow [code unfold]: "f ^ n = fun_pow n f"
+lemma funpow_fun_pow [code unfold]:
+ "f ^^ n = fun_pow n f"
unfolding funpow_def fun_pow_def ..
-lemma funpow_add: "f ^ (m+n) = f^m o f^n"
+lemma funpow_add:
+ "f ^^ (m + n) = f ^^ m o f ^^ n"
by (induct m) simp_all
-lemma funpow_swap1: "f((f^n) x) = (f^n)(f x)"
+lemma funpow_swap1:
+ "f ((f ^^ n) x) = (f ^^ n) (f x)"
proof -
- have "f((f^n) x) = (f^(n+1)) x" unfolding One_nat_def by simp
- also have "\<dots> = (f^n o f^1) x" by (simp only: funpow_add)
- also have "\<dots> = (f^n)(f x)" unfolding One_nat_def by simp
+ have "f ((f ^^ n) x) = (f ^^ (n+1)) x" unfolding One_nat_def by simp
+ also have "\<dots> = (f ^^ n o f ^^ 1) x" by (simp only: funpow_add)
+ also have "\<dots> = (f ^^ n) (f x)" unfolding One_nat_def by simp
finally show ?thesis .
qed
lemma rel_pow_1 [simp]:
- fixes R :: "('a*'a)set"
- shows "R^1 = R"
- unfolding One_nat_def by simp
-
-lemma rel_pow_0_I: "(x,x) : R^0"
+ fixes R :: "('a * 'a) set"
+ shows "R ^^ 1 = R"
by simp
-lemma rel_pow_Suc_I: "[| (x,y) : R^n; (y,z):R |] ==> (x,z):R^(Suc n)"
+lemma rel_pow_0_I:
+ "(x, x) \<in> R ^^ 0"
+ by simp
+
+lemma rel_pow_Suc_I:
+ "(x, y) \<in> R ^^ n \<Longrightarrow> (y, z) \<in> R \<Longrightarrow> (x, z) \<in> R ^^ Suc n"
by auto
lemma rel_pow_Suc_I2:
- "(x, y) : R \<Longrightarrow> (y, z) : R^n \<Longrightarrow> (x,z) : R^(Suc n)"
- apply (induct n arbitrary: z)
- apply simp
- apply fastsimp
- done
+ "(x, y) \<in> R \<Longrightarrow> (y, z) \<in> R ^^ n \<Longrightarrow> (x, z) \<in> R ^^ Suc n"
+ by (induct n arbitrary: z) (simp, fastsimp)
-lemma rel_pow_0_E: "[| (x,y) : R^0; x=y ==> P |] ==> P"
+lemma rel_pow_0_E:
+ "(x, y) \<in> R ^^ 0 \<Longrightarrow> (x = y \<Longrightarrow> P) \<Longrightarrow> P"
by simp
lemma rel_pow_Suc_E:
- "[| (x,z) : R^(Suc n); !!y. [| (x,y) : R^n; (y,z) : R |] ==> P |] ==> P"
+ "(x, z) \<in> R ^^ Suc n \<Longrightarrow> (\<And>y. (x, y) \<in> R ^^ n \<Longrightarrow> (y, z) \<in> R \<Longrightarrow> P) \<Longrightarrow> P"
by auto
lemma rel_pow_E:
- "[| (x,z) : R^n; [| n=0; x = z |] ==> P;
- !!y m. [| n = Suc m; (x,y) : R^m; (y,z) : R |] ==> P
- |] ==> P"
+ "(x, z) \<in> R ^^ n \<Longrightarrow> (n = 0 \<Longrightarrow> x = z \<Longrightarrow> P)
+ \<Longrightarrow> (\<And>y m. n = Suc m \<Longrightarrow> (x, y) \<in> R ^^ m \<Longrightarrow> (y, z) \<in> R \<Longrightarrow> P)
+ \<Longrightarrow> P"
by (cases n) auto
lemma rel_pow_Suc_D2:
- "(x, z) : R^(Suc n) \<Longrightarrow> (\<exists>y. (x,y) : R & (y,z) : R^n)"
+ "(x, z) \<in> R ^^ Suc n \<Longrightarrow> (\<exists>y. (x, y) \<in> R \<and> (y, z) \<in> R ^^ n)"
apply (induct n arbitrary: x z)
apply (blast intro: rel_pow_0_I elim: rel_pow_0_E rel_pow_Suc_E)
apply (blast intro: rel_pow_Suc_I elim: rel_pow_0_E rel_pow_Suc_E)
done
lemma rel_pow_Suc_D2':
- "\<forall>x y z. (x,y) : R^n & (y,z) : R --> (\<exists>w. (x,w) : R & (w,z) : R^n)"
+ "\<forall>x y z. (x, y) \<in> R ^^ n \<and> (y, z) \<in> R \<longrightarrow> (\<exists>w. (x, w) \<in> R \<and> (w, z) \<in> R ^^ n)"
by (induct n) (simp_all, blast)
lemma rel_pow_E2:
- "[| (x,z) : R^n; [| n=0; x = z |] ==> P;
- !!y m. [| n = Suc m; (x,y) : R; (y,z) : R^m |] ==> P
- |] ==> P"
- apply (case_tac n, simp)
+ "(x, z) \<in> R ^^ n \<Longrightarrow> (n = 0 \<Longrightarrow> x = z \<Longrightarrow> P)
+ \<Longrightarrow> (\<And>y m. n = Suc m \<Longrightarrow> (x, y) \<in> R \<Longrightarrow> (y, z) \<in> R ^^ m \<Longrightarrow> P)
+ \<Longrightarrow> P"
+ apply (cases n, simp)
apply (cut_tac n=nat and R=R in rel_pow_Suc_D2', simp, blast)
done
-lemma rtrancl_imp_UN_rel_pow: "!!p. p:R^* ==> p : (UN n. R^n)"
- apply (simp only: split_tupled_all)
+lemma rtrancl_imp_UN_rel_pow:
+ "p \<in> R^* \<Longrightarrow> p \<in> (\<Union>n. R ^^ n)"
+ apply (cases p) apply (simp only:)
apply (erule rtrancl_induct)
apply (blast intro: rel_pow_0_I rel_pow_Suc_I)+
done
-lemma rel_pow_imp_rtrancl: "!!p. p:R^n ==> p:R^*"
- apply (simp only: split_tupled_all)
- apply (induct n)
+lemma rel_pow_imp_rtrancl:
+ "p \<in> R ^^ n \<Longrightarrow> p \<in> R^*"
+ apply (induct n arbitrary: p)
+ apply (simp_all only: split_tupled_all)
apply (blast intro: rtrancl_refl elim: rel_pow_0_E)
apply (blast elim: rel_pow_Suc_E intro: rtrancl_into_rtrancl)
done
-lemma rtrancl_is_UN_rel_pow: "R^* = (UN n. R^n)"
+lemma rtrancl_is_UN_rel_pow:
+ "R^* = (UN n. R ^^ n)"
by (blast intro: rtrancl_imp_UN_rel_pow rel_pow_imp_rtrancl)
lemma trancl_power:
- "x \<in> r^+ = (\<exists>n > 0. x \<in> r^n)"
+ "x \<in> r^+ = (\<exists>n > 0. x \<in> r ^^ n)"
apply (cases x)
apply simp
apply (rule iffI)
@@ -151,30 +143,12 @@
done
lemma single_valued_rel_pow:
- "!!r::('a * 'a)set. single_valued r ==> single_valued (r^n)"
+ fixes R :: "('a * 'a) set"
+ shows "single_valued R \<Longrightarrow> single_valued (R ^^ n)"
+ apply (induct n arbitrary: R)
+ apply simp_all
apply (rule single_valuedI)
- apply (induct n)
- apply simp
apply (fast dest: single_valuedD elim: rel_pow_Suc_E)
done
-ML
-{*
-val funpow_add = thm "funpow_add";
-val rel_pow_1 = thm "rel_pow_1";
-val rel_pow_0_I = thm "rel_pow_0_I";
-val rel_pow_Suc_I = thm "rel_pow_Suc_I";
-val rel_pow_Suc_I2 = thm "rel_pow_Suc_I2";
-val rel_pow_0_E = thm "rel_pow_0_E";
-val rel_pow_Suc_E = thm "rel_pow_Suc_E";
-val rel_pow_E = thm "rel_pow_E";
-val rel_pow_Suc_D2 = thm "rel_pow_Suc_D2";
-val rel_pow_Suc_D2 = thm "rel_pow_Suc_D2";
-val rel_pow_E2 = thm "rel_pow_E2";
-val rtrancl_imp_UN_rel_pow = thm "rtrancl_imp_UN_rel_pow";
-val rel_pow_imp_rtrancl = thm "rel_pow_imp_rtrancl";
-val rtrancl_is_UN_rel_pow = thm "rtrancl_is_UN_rel_pow";
-val single_valued_rel_pow = thm "single_valued_rel_pow";
-*}
-
end
--- a/src/HOL/Ring_and_Field.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Ring_and_Field.thy Mon May 11 17:20:52 2009 +0200
@@ -2226,15 +2226,21 @@
qed
qed
-instance ordered_idom \<subseteq> pordered_ring_abs
-by default (auto simp add: abs_if not_less
- equal_neg_zero neg_equal_zero mult_less_0_iff)
-
-lemma abs_mult: "abs (a * b) = abs a * abs (b::'a::ordered_idom)"
-by (simp add: abs_eq_mult linorder_linear)
-
-lemma abs_mult_self: "abs a * abs a = a * (a::'a::ordered_idom)"
-by (simp add: abs_if)
+context ordered_idom
+begin
+
+subclass pordered_ring_abs proof
+qed (auto simp add: abs_if not_less equal_neg_zero neg_equal_zero mult_less_0_iff)
+
+lemma abs_mult:
+ "abs (a * b) = abs a * abs b"
+ by (rule abs_eq_mult) auto
+
+lemma abs_mult_self:
+ "abs a * abs a = a * a"
+ by (simp add: abs_if)
+
+end
lemma nonzero_abs_inverse:
"a \<noteq> 0 ==> abs (inverse (a::'a::ordered_field)) = inverse (abs a)"
--- a/src/HOL/SEQ.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/SEQ.thy Mon May 11 17:20:52 2009 +0200
@@ -487,7 +487,7 @@
by (simp add: LIMSEQ_mult LIMSEQ_inverse divide_inverse)
lemma LIMSEQ_pow:
- fixes a :: "'a::{real_normed_algebra,recpower}"
+ fixes a :: "'a::{power, real_normed_algebra}"
shows "X ----> a \<Longrightarrow> (\<lambda>n. (X n) ^ m) ----> a ^ m"
by (induct m) (simp_all add: LIMSEQ_const LIMSEQ_mult)
@@ -1394,7 +1394,7 @@
qed
lemma LIMSEQ_power_zero:
- fixes x :: "'a::{real_normed_algebra_1,recpower}"
+ fixes x :: "'a::{real_normed_algebra_1}"
shows "norm x < 1 \<Longrightarrow> (\<lambda>n. x ^ n) ----> 0"
apply (drule LIMSEQ_realpow_zero [OF norm_ge_zero])
apply (simp only: LIMSEQ_Zseq_iff, erule Zseq_le)
--- a/src/HOL/Series.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Series.thy Mon May 11 17:20:52 2009 +0200
@@ -331,7 +331,7 @@
lemmas sumr_geometric = geometric_sum [where 'a = real]
lemma geometric_sums:
- fixes x :: "'a::{real_normed_field,recpower}"
+ fixes x :: "'a::{real_normed_field}"
shows "norm x < 1 \<Longrightarrow> (\<lambda>n. x ^ n) sums (1 / (1 - x))"
proof -
assume less_1: "norm x < 1"
@@ -348,7 +348,7 @@
qed
lemma summable_geometric:
- fixes x :: "'a::{real_normed_field,recpower}"
+ fixes x :: "'a::{real_normed_field}"
shows "norm x < 1 \<Longrightarrow> summable (\<lambda>n. x ^ n)"
by (rule geometric_sums [THEN sums_summable])
@@ -434,7 +434,7 @@
text{*Summability of geometric series for real algebras*}
lemma complete_algebra_summable_geometric:
- fixes x :: "'a::{real_normed_algebra_1,banach,recpower}"
+ fixes x :: "'a::{real_normed_algebra_1,banach}"
shows "norm x < 1 \<Longrightarrow> summable (\<lambda>n. x ^ n)"
proof (rule summable_comparison_test)
show "\<exists>N. \<forall>n\<ge>N. norm (x ^ n) \<le> norm x ^ n"
--- a/src/HOL/SetInterval.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/SetInterval.thy Mon May 11 17:20:52 2009 +0200
@@ -397,6 +397,22 @@
apply (rule_tac [2] finite_lessThan, auto)
done
+text {* A set of natural numbers is finite iff it is bounded. *}
+lemma finite_nat_set_iff_bounded:
+ "finite(N::nat set) = (EX m. ALL n:N. n<m)" (is "?F = ?B")
+proof
+ assume f:?F show ?B
+ using Max_ge[OF `?F`, simplified less_Suc_eq_le[symmetric]] by blast
+next
+ assume ?B show ?F using `?B` by(blast intro:bounded_nat_set_is_finite)
+qed
+
+lemma finite_nat_set_iff_bounded_le:
+ "finite(N::nat set) = (EX m. ALL n:N. n<=m)"
+apply(simp add:finite_nat_set_iff_bounded)
+apply(blast dest:less_imp_le_nat le_imp_less_Suc)
+done
+
lemma finite_less_ub:
"!!f::nat=>nat. (!!n. n \<le> f n) ==> finite {n. f n \<le> u}"
by (rule_tac B="{..u}" in finite_subset, auto intro: order_trans)
@@ -855,7 +871,7 @@
lemma geometric_sum:
"x ~= 1 ==> (\<Sum>i=0..<n. x ^ i) =
- (x ^ n - 1) / (x - 1::'a::{field, recpower})"
+ (x ^ n - 1) / (x - 1::'a::{field})"
by (induct "n") (simp_all add:field_simps power_Suc)
subsection {* The formula for arithmetic sums *}
--- a/src/HOL/SizeChange/Graphs.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/SizeChange/Graphs.thy Mon May 11 17:20:52 2009 +0200
@@ -228,18 +228,8 @@
qed
qed
-instantiation graph :: (type, monoid_mult) "{semiring_1, idem_add, recpower, star}"
-begin
-
-primrec power_graph :: "('a\<Colon>type, 'b\<Colon>monoid_mult) graph \<Rightarrow> nat => ('a, 'b) graph"
-where
- "(A \<Colon> ('a, 'b) graph) ^ 0 = 1"
-| "(A \<Colon> ('a, 'b) graph) ^ Suc n = A * (A ^ n)"
-
-definition
- graph_star_def: "star (G \<Colon> ('a, 'b) graph) = (SUP n. G ^ n)"
-
-instance proof
+instance graph :: (type, monoid_mult) "{semiring_1, idem_add}"
+proof
fix a b c :: "('a, 'b) graph"
show "1 * a = a"
@@ -258,10 +248,16 @@
show "a + a = a" unfolding graph_plus_def by simp
- show "a ^ 0 = 1" "\<And>n. a ^ (Suc n) = a * a ^ n"
- by simp_all
qed
+instantiation graph :: (type, monoid_mult) star
+begin
+
+definition
+ graph_star_def: "star (G \<Colon> ('a, 'b) graph) = (SUP n. G ^ n)"
+
+instance ..
+
end
lemma graph_leqI:
@@ -351,7 +347,7 @@
lemma in_tcl:
"has_edge (tcl G) a x b = (\<exists>n>0. has_edge (G ^ n) a x b)"
- apply (auto simp: tcl_is_SUP in_SUP simp del: power_graph.simps power_Suc)
+ apply (auto simp: tcl_is_SUP in_SUP simp del: power.simps power_Suc)
apply (rule_tac x = "n - 1" in exI, auto)
done
--- a/src/HOL/SizeChange/Interpretation.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/SizeChange/Interpretation.thy Mon May 11 17:20:52 2009 +0200
@@ -35,7 +35,7 @@
and nia: "\<And>x. \<not>accp R x \<Longrightarrow> \<not>accp R (f x)"
by blast
- let ?s = "\<lambda>i. (f ^ i) x"
+ let ?s = "\<lambda>i. (f ^^ i) x"
{
fix i
--- a/src/HOL/SizeChange/Kleene_Algebras.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/SizeChange/Kleene_Algebras.thy Mon May 11 17:20:52 2009 +0200
@@ -97,7 +97,7 @@
and star4: "x * a \<le> x \<Longrightarrow> x * star a \<le> x"
class kleene_by_complete_lattice = pre_kleene
- + complete_lattice + recpower + star +
+ + complete_lattice + power + star +
assumes star_cont: "a * star b * c = SUPR UNIV (\<lambda>n. a * b ^ n * c)"
begin
--- a/src/HOL/SizeChange/Size_Change_Termination.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/SizeChange/Size_Change_Termination.thy Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title: HOL/Library/Size_Change_Termination.thy
- ID: $Id$
Author: Alexander Krauss, TU Muenchen
*)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/String.thy Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,150 @@
+(* Author: Tobias Nipkow, Florian Haftmann, TU Muenchen *)
+
+header {* Character and string types *}
+
+theory String
+imports List
+uses
+ "Tools/string_syntax.ML"
+ ("Tools/string_code.ML")
+begin
+
+subsection {* Characters *}
+
+datatype nibble =
+ Nibble0 | Nibble1 | Nibble2 | Nibble3 | Nibble4 | Nibble5 | Nibble6 | Nibble7
+ | Nibble8 | Nibble9 | NibbleA | NibbleB | NibbleC | NibbleD | NibbleE | NibbleF
+
+lemma UNIV_nibble:
+ "UNIV = {Nibble0, Nibble1, Nibble2, Nibble3, Nibble4, Nibble5, Nibble6, Nibble7,
+ Nibble8, Nibble9, NibbleA, NibbleB, NibbleC, NibbleD, NibbleE, NibbleF}" (is "_ = ?A")
+proof (rule UNIV_eq_I)
+ fix x show "x \<in> ?A" by (cases x) simp_all
+qed
+
+instance nibble :: finite
+ by default (simp add: UNIV_nibble)
+
+datatype char = Char nibble nibble
+ -- "Note: canonical order of character encoding coincides with standard term ordering"
+
+lemma UNIV_char:
+ "UNIV = image (split Char) (UNIV \<times> UNIV)"
+proof (rule UNIV_eq_I)
+ fix x show "x \<in> image (split Char) (UNIV \<times> UNIV)" by (cases x) auto
+qed
+
+instance char :: finite
+ by default (simp add: UNIV_char)
+
+lemma size_char [code, simp]:
+ "size (c::char) = 0" by (cases c) simp
+
+lemma char_size [code, simp]:
+ "char_size (c::char) = 0" by (cases c) simp
+
+primrec nibble_pair_of_char :: "char \<Rightarrow> nibble \<times> nibble" where
+ "nibble_pair_of_char (Char n m) = (n, m)"
+
+declare nibble_pair_of_char.simps [code del]
+
+setup {*
+let
+ val nibbles = map (Thm.cterm_of @{theory} o HOLogic.mk_nibble) (0 upto 15);
+ val thms = map_product
+ (fn n => fn m => Drule.instantiate' [] [SOME n, SOME m] @{thm nibble_pair_of_char.simps})
+ nibbles nibbles;
+in
+ PureThy.note_thmss Thm.lemmaK [((Binding.name "nibble_pair_of_char_simps", []), [(thms, [])])]
+ #-> (fn [(_, thms)] => fold_rev Code.add_eqn thms)
+end
+*}
+
+lemma char_case_nibble_pair [code, code inline]:
+ "char_case f = split f o nibble_pair_of_char"
+ by (simp add: expand_fun_eq split: char.split)
+
+lemma char_rec_nibble_pair [code, code inline]:
+ "char_rec f = split f o nibble_pair_of_char"
+ unfolding char_case_nibble_pair [symmetric]
+ by (simp add: expand_fun_eq split: char.split)
+
+syntax
+ "_Char" :: "xstr => char" ("CHR _")
+
+
+subsection {* Strings *}
+
+types string = "char list"
+
+syntax
+ "_String" :: "xstr => string" ("_")
+
+setup StringSyntax.setup
+
+
+subsection {* Strings as dedicated datatype *}
+
+datatype message_string = STR string
+
+lemmas [code del] =
+ message_string.recs message_string.cases
+
+lemma [code]: "size (s\<Colon>message_string) = 0"
+ by (cases s) simp_all
+
+lemma [code]: "message_string_size (s\<Colon>message_string) = 0"
+ by (cases s) simp_all
+
+
+subsection {* Code generator *}
+
+use "Tools/string_code.ML"
+
+code_type message_string
+ (SML "string")
+ (OCaml "string")
+ (Haskell "String")
+
+setup {*
+ fold String_Code.add_literal_message ["SML", "OCaml", "Haskell"]
+*}
+
+code_instance message_string :: eq
+ (Haskell -)
+
+code_const "eq_class.eq \<Colon> message_string \<Rightarrow> message_string \<Rightarrow> bool"
+ (SML "!((_ : string) = _)")
+ (OCaml "!((_ : string) = _)")
+ (Haskell infixl 4 "==")
+
+code_reserved SML string
+code_reserved OCaml string
+
+
+types_code
+ "char" ("string")
+attach (term_of) {*
+val term_of_char = HOLogic.mk_char o ord;
+*}
+attach (test) {*
+fun gen_char i =
+ let val j = random_range (ord "a") (Int.min (ord "a" + i, ord "z"))
+ in (chr j, fn () => HOLogic.mk_char j) end;
+*}
+
+setup {*
+let
+
+fun char_codegen thy defs dep thyname b t gr =
+ let
+ val i = HOLogic.dest_char t;
+ val (_, gr') = Codegen.invoke_tycodegen thy defs dep thyname false
+ (fastype_of t) gr;
+ in SOME (Codegen.str (ML_Syntax.print_string (chr i)), gr')
+ end handle TERM _ => NONE;
+
+in Codegen.add_codegen "char_codegen" char_codegen end
+*}
+
+end
\ No newline at end of file
--- a/src/HOL/Sum_Type.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Sum_Type.thy Mon May 11 17:20:52 2009 +0200
@@ -157,6 +157,8 @@
apply auto
done
+lemma Plus_eq_empty_conv[simp]: "A <+> B = {} \<longleftrightarrow> A = {} \<and> B = {}"
+by(auto)
subsection{*The @{term Part} Primitive*}
--- a/src/HOL/Tools/Qelim/presburger.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/Qelim/presburger.ML Mon May 11 17:20:52 2009 +0200
@@ -131,7 +131,7 @@
@{thm "div_0"}, @{thm "mod_0"}, @{thm "div_by_1"}, @{thm "mod_by_1"}, @{thm "div_1"},
@{thm "mod_1"}, @{thm "Suc_plus1"}]
@ @{thms add_ac}
- addsimprocs [cancel_div_mod_proc]
+ addsimprocs [cancel_div_mod_nat_proc, cancel_div_mod_int_proc]
val splits_ss = comp_ss addsimps [@{thm "mod_div_equality'"}] addsplits
[@{thm "split_zdiv"}, @{thm "split_zmod"}, @{thm "split_div'"},
@{thm "split_min"}, @{thm "split_max"}, @{thm "abs_split"}]
--- a/src/HOL/Tools/atp_manager.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/atp_manager.ML Mon May 11 17:20:52 2009 +0200
@@ -19,9 +19,11 @@
val kill: unit -> unit
val info: unit -> unit
val messages: int option -> unit
- type prover = int -> int -> Proof.context * (thm list * thm) -> bool * string
+ type prover = int -> (thm * (string * int)) list option -> string -> int ->
+ Proof.context * (thm list * thm) -> bool * string * string * string vector
val add_prover: string -> prover -> theory -> theory
val print_provers: theory -> unit
+ val get_prover: string -> theory -> prover option
val sledgehammer: string list -> Proof.state -> unit
end;
@@ -51,15 +53,17 @@
fun set_timeout time = CRITICAL (fn () => timeout := time);
val _ =
- ProofGeneralPgip.add_preference "Proof"
+ ProofGeneralPgip.add_preference Preferences.category_proof
(Preferences.string_pref atps
"ATP: provers" "Default automatic provers (separated by whitespace)");
-val _ = ProofGeneralPgip.add_preference "Proof"
+val _ =
+ ProofGeneralPgip.add_preference Preferences.category_proof
(Preferences.int_pref max_atps
"ATP: maximum number" "How many provers may run in parallel");
-val _ = ProofGeneralPgip.add_preference "Proof"
+val _ =
+ ProofGeneralPgip.add_preference Preferences.category_proof
(Preferences.int_pref timeout
"ATP: timeout" "ATPs will be interrupted after this time (in seconds)");
@@ -284,7 +288,8 @@
(* named provers *)
-type prover = int -> int -> Proof.context * (thm list * thm) -> bool * string;
+type prover = int -> (thm * (string * int)) list option -> string -> int ->
+ Proof.context * (thm list * thm) -> bool * string * string * string vector
fun err_dup_prover name = error ("Duplicate prover: " ^ quote name);
@@ -305,13 +310,16 @@
fun print_provers thy = Pretty.writeln
(Pretty.strs ("external provers:" :: sort_strings (Symtab.keys (Provers.get thy))));
+fun get_prover name thy = case Symtab.lookup (Provers.get thy) name of
+ NONE => NONE
+| SOME (prover, _) => SOME prover;
(* start prover thread *)
fun start_prover name birthtime deadtime i proof_state =
- (case Symtab.lookup (Provers.get (Proof.theory_of proof_state)) name of
+ (case get_prover name (Proof.theory_of proof_state) of
NONE => warning ("Unknown external prover: " ^ quote name)
- | SOME (prover, _) =>
+ | SOME prover =>
let
val (ctxt, (_, goal)) = Proof.get_goal proof_state
val desc =
@@ -320,7 +328,10 @@
val _ = SimpleThread.fork true (fn () =>
let
val _ = register birthtime deadtime (Thread.self (), desc)
- val result = prover (get_timeout ()) i (Proof.get_goal proof_state)
+ val result =
+ let val (success, message, _, _) =
+ prover (get_timeout ()) NONE name i (Proof.get_goal proof_state)
+ in (success, message) end
handle ResHolClause.TOO_TRIVIAL
=> (true, "Empty clause: Try this command: " ^ Markup.markup Markup.sendback "apply metis")
| ERROR msg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Tools/atp_minimal.ML Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,201 @@
+(* Title: HOL/Tools/atp_minimal.ML
+ Author: Philipp Meyer, TU Muenchen
+
+Minimalization of theorem list for metis by using an external automated theorem prover
+*)
+
+structure AtpMinimal =
+struct
+
+ (* output control *)
+ fun debug str = Output.debug (fn () => str)
+ fun debug_fn f = if !Output.debugging then f() else ()
+ fun answer str = Output.writeln str
+ fun println str = Output.priority str
+
+ fun order_unique name_list = OrdList.make (String.collate Char.compare) name_list
+ fun length_string namelist = Int.toString (length namelist)
+
+ fun print_names name_thms_pairs =
+ let
+ val names = (map fst name_thms_pairs)
+ val ordered = order_unique names
+ in
+ app (fn name => (debug (" " ^ name))) ordered
+ end
+
+ (* minimalization algorithm *)
+ local
+ fun isplit (l,r) [] = (l,r)
+ | isplit (l,r) (h::[]) = (h::l, r)
+ | isplit (l,r) (h1::h2::t) = isplit (h1::l, h2::r) t
+ in
+ fun split lst = isplit ([],[]) lst
+ end
+
+ local
+ fun min p sup [] = raise Empty
+ | min p sup [s0] = [s0]
+ | min p sup s =
+ let
+ val (l0, r0) = split s
+ in
+ if p(sup @ l0)
+ then min p sup l0
+ else
+ if p(sup @ r0)
+ then min p sup r0
+ else
+ let
+ val l = min p (sup @ r0) l0
+ val r = min p (sup @ l) r0
+ in
+ l @ r
+ end
+ end
+ in
+ (* return a minimal subset v of s that satisfies p
+ @pre p(s) & ~p([]) & monotone(p)
+ @post v subset s & p(v) &
+ forall e in v. ~p(v \ e)
+ *)
+ fun minimal p s = min p [] s
+ end
+
+ (* failure check and producing answer*)
+ datatype 'a prove_result = Success of 'a | Failure | Timeout | Error
+
+ val string_of_result = fn
+ Success _ => "Success"
+ | Failure => "Failure"
+ | Timeout => "Timeout"
+ | Error => "Error"
+
+ val failure_strings =
+ [("SPASS beiseite: Ran out of time.", Timeout),
+ ("Timeout", Timeout),
+ ("time limit exceeded", Timeout),
+ ("# Cannot determine problem status within resource limit", Timeout),
+ ("Error", Error)]
+
+ fun produce_answer (success, message, result_string, thm_name_vec) =
+ if success then
+ (Success (Vector.foldr op:: [] thm_name_vec), result_string)
+ else
+ let
+ val failure = get_first (fn (s, t) => if String.isSubstring s result_string then SOME (t, result_string) else NONE) failure_strings
+ in
+ if is_some failure then
+ the failure
+ else
+ (Failure, result_string)
+ end
+
+ (* wrapper for calling external prover *)
+ fun sh_test_thms prover prover_name time_limit subgoalno state name_thms_pairs =
+ let
+ val _ = println ("Testing " ^ (length_string name_thms_pairs) ^ " theorems... ")
+ val name_thm_pairs = flat (map (fn (n, ths) => map_index (fn (i, th) => (n, th)) ths) name_thms_pairs)
+ val _ = debug_fn (fn () => print_names name_thm_pairs)
+ val axclauses = ResAxioms.cnf_rules_pairs (Proof.theory_of state) name_thm_pairs
+ val (result, proof) =
+ (produce_answer (prover time_limit (SOME axclauses) prover_name subgoalno (Proof.get_goal state)))
+ val _ = println (string_of_result result)
+ val _ = debug proof
+ in
+ (result, proof)
+ end
+
+ (* minimalization of thms *)
+ fun minimalize prover prover_name time_limit state name_thms_pairs =
+ let
+ val _ = println ("Minimize called with " ^ (length_string name_thms_pairs) ^ " theorems, prover: "
+ ^ prover_name ^ ", time limit: " ^ (Int.toString time_limit) ^ " seconds")
+ val _ = debug_fn (fn () => app (fn (n, tl) => (debug n; app (fn t => debug (" " ^ Display.string_of_thm t)) tl)) name_thms_pairs)
+ val test_thms_fun = sh_test_thms prover prover_name time_limit 1 state
+ fun test_thms thms = case test_thms_fun thms of (Success _, _) => true | _ => false
+ in
+ (* try proove first to check result and get used theorems *)
+ (case test_thms_fun name_thms_pairs of
+ (Success used, _) =>
+ let
+ val ordered_used = order_unique used
+ val to_use =
+ if length ordered_used < length name_thms_pairs then
+ filter (fn (name1, _) => List.exists (equal name1) ordered_used) name_thms_pairs
+ else
+ name_thms_pairs
+ val min_thms = (minimal test_thms to_use)
+ val min_names = order_unique (map fst min_thms)
+ val _ = println ("Minimal " ^ (length_string min_thms) ^ " theorems")
+ val _ = debug_fn (fn () => print_names min_thms)
+ in
+ answer ("Try this command: " ^ Markup.markup Markup.sendback ("apply (metis " ^ (space_implode " " min_names) ^ ")"))
+ end
+ | (Timeout, _) =>
+ answer ("Timeout: You may need to increase the time limit of " ^ (Int.toString time_limit) ^ " seconds. Call atp_minimize [time=...] ")
+ | (Error, msg) =>
+ answer ("Error in prover: " ^ msg)
+ | (Failure, _) =>
+ answer "Failure: No proof with the theorems supplied")
+ handle ResHolClause.TOO_TRIVIAL =>
+ answer ("Trivial: Try this command: " ^ Markup.markup Markup.sendback "apply metis")
+ | ERROR msg =>
+ answer ("Error: " ^ msg)
+ end
+
+ (* isar command and parsing input *)
+
+ local structure K = OuterKeyword and P = OuterParse and T = OuterLex in
+
+ fun get_thms context =
+ map (fn (name, interval) =>
+ let
+ val thmref = Facts.Named ((name, Position.none), interval)
+ val ths = ProofContext.get_fact context thmref
+ val name' = Facts.string_of_ref thmref
+ in
+ (name', ths)
+ end)
+
+ val default_prover = "remote_vampire"
+ val default_time_limit = 5
+
+ fun get_time_limit_arg time_string =
+ (case Int.fromString time_string of
+ SOME t => t
+ | NONE => error ("Invalid time limit: " ^ quote time_string))
+
+ val get_options =
+ let
+ val def = (default_prover, default_time_limit)
+ in
+ foldl (fn ((name, a), (p, t)) => (case name of
+ "time" => (p, (get_time_limit_arg a))
+ | "atp" => (a, t)
+ | n => error ("Invalid argument: " ^ n))) def
+ end
+
+ fun sh_min_command args thm_names state =
+ let
+ val (prover_name, time_limit) = get_options args
+ val prover =
+ case AtpManager.get_prover prover_name (Proof.theory_of state) of
+ SOME prover => prover
+ | NONE => error ("Unknown prover: " ^ quote prover_name)
+ val name_thms_pairs = get_thms (Proof.context_of state) thm_names
+ in
+ minimalize prover prover_name time_limit state name_thms_pairs
+ end
+
+ val parse_args = Scan.optional (Args.bracks (P.list (P.xname --| P.$$$ "=" -- P.xname) )) []
+ val parse_thm_names = Scan.repeat (P.xname -- Scan.option Attrib.thm_sel)
+
+ val _ =
+ OuterSyntax.command "atp_minimize" "minimize theorem list with external prover" K.diag
+ (parse_args -- parse_thm_names >> (fn (args, thm_names) =>
+ Toplevel.no_timing o Toplevel.unknown_proof o Toplevel.keep ((sh_min_command args thm_names) o Toplevel.proof_of)))
+
+ end
+end
+
--- a/src/HOL/Tools/atp_wrapper.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/atp_wrapper.ML Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title: HOL/Tools/atp_wrapper.ML
- ID: $Id$
Author: Fabian Immler, TU Muenchen
Wrapper functions for external ATPs.
@@ -10,10 +9,10 @@
val destdir: string ref
val problem_name: string ref
val external_prover:
- (thm * (string * int)) list ->
+ (unit -> (thm * (string * int)) list) ->
(Path.T -> thm -> int -> (thm * (string * int)) list -> theory -> string vector) ->
Path.T * string -> (string -> string option) ->
- (string * string vector * Proof.context * thm * int -> string) ->
+ (string -> string * string vector * Proof.context * thm * int -> string) ->
AtpManager.prover
val tptp_prover_opts_full: int -> bool -> bool -> Path.T * string -> AtpManager.prover
val tptp_prover_opts: int -> bool -> Path.T * string -> AtpManager.prover
@@ -47,7 +46,8 @@
(* basic template *)
-fun external_prover axiom_clauses write_problem_file (cmd, args) find_failure produce_answer timeout subgoalno goal =
+fun external_prover relevance_filter write_problem_file (cmd, args) find_failure produce_answer
+ timeout axiom_clauses name subgoalno goal =
let
(* path to unique problem file *)
val destdir' = ! destdir
@@ -66,7 +66,8 @@
val chain_ths = map (Thm.put_name_hint ResReconstruct.chained_hint) chain_ths
val probfile = prob_pathname subgoalno
val fname = File.platform_path probfile
- val thm_names = write_problem_file probfile th subgoalno axiom_clauses thy
+ val the_ax_clauses = case axiom_clauses of NONE => relevance_filter () | SOME axcls => axcls
+ val thm_names = write_problem_file probfile th subgoalno the_ax_clauses thy
val cmdline =
if File.exists cmd then "exec " ^ File.shell_path cmd ^ " " ^ args
else error ("Bad executable: " ^ Path.implode cmd)
@@ -81,7 +82,7 @@
val message =
if is_some failure then "External prover failed."
else if rc <> 0 then "External prover failed: " ^ proof
- else "Try this command: " ^ produce_answer (proof, thm_names, ctxt, th, subgoalno)
+ else "Try this command: " ^ produce_answer name (proof, thm_names, ctxt, th, subgoalno)
val _ =
if is_some failure
@@ -91,7 +92,7 @@
if rc <> 0
then Output.debug (fn () => "Sledgehammer exited with return code " ^ string_of_int rc ^ ":\n" ^ proof)
else ()
- in (success, message) end;
+ in (success, message, proof, thm_names) end;
@@ -99,14 +100,14 @@
(* generic TPTP-based provers *)
-fun tptp_prover_opts_full max_new theory_const full command timeout n goal =
+fun tptp_prover_opts_full max_new theory_const full command timeout ax_clauses name n goal =
external_prover
- (ResAtp.get_relevant max_new theory_const goal n)
+ (fn () => ResAtp.get_relevant max_new theory_const goal n)
(ResAtp.write_problem_file false)
command
ResReconstruct.find_failure
(if full then ResReconstruct.structured_proof else ResReconstruct.lemma_list_tstp)
- timeout n goal;
+ timeout ax_clauses name n goal;
(*arbitrary ATP with TPTP input/output and problemfile as last argument*)
fun tptp_prover_opts max_new theory_const =
@@ -163,14 +164,14 @@
(* SPASS *)
-fun spass_opts max_new theory_const timeout n goal = external_prover
- (ResAtp.get_relevant max_new theory_const goal n)
+fun spass_opts max_new theory_const timeout ax_clauses name n goal = external_prover
+ (fn () => ResAtp.get_relevant max_new theory_const goal n)
(ResAtp.write_problem_file true)
(Path.explode "$SPASS_HOME/SPASS",
"-Auto -SOS=1 -PGiven=0 -PProblem=0 -Splits=0 -FullRed=0 -DocProof -TimeLimit=" ^ string_of_int timeout)
ResReconstruct.find_failure
ResReconstruct.lemma_list_dfg
- timeout n goal;
+ timeout ax_clauses name n goal;
val spass = spass_opts 40 true;
@@ -179,7 +180,7 @@
fun remote_prover_opts max_new theory_const args timeout =
tptp_prover_opts max_new theory_const
- (Path.explode "$ISABELLE_HOME/contrib/SystemOnTPTP/remote", args ^ " -t " ^ string_of_int timeout)
+ (Path.explode "$ISABELLE_HOME/lib/scripts/SystemOnTPTP", args ^ " -t " ^ string_of_int timeout)
timeout;
val remote_prover = remote_prover_opts 60 false;
--- a/src/HOL/Tools/hologic.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/hologic.ML Mon May 11 17:20:52 2009 +0200
@@ -116,6 +116,9 @@
val stringT: typ
val mk_string: string -> term
val dest_string: term -> string
+ val message_stringT: typ
+ val mk_message_string: string -> term
+ val dest_message_string: term -> string
end;
structure HOLogic: HOLOGIC =
@@ -510,44 +513,6 @@
val realT = Type ("RealDef.real", []);
-(* nibble *)
-
-val nibbleT = Type ("List.nibble", []);
-
-fun mk_nibble n =
- let val s =
- if 0 <= n andalso n <= 9 then chr (n + ord "0")
- else if 10 <= n andalso n <= 15 then chr (n + ord "A" - 10)
- else raise TERM ("mk_nibble", [])
- in Const ("List.nibble.Nibble" ^ s, nibbleT) end;
-
-fun dest_nibble t =
- let fun err () = raise TERM ("dest_nibble", [t]) in
- (case try (unprefix "List.nibble.Nibble" o fst o Term.dest_Const) t of
- NONE => err ()
- | SOME c =>
- if size c <> 1 then err ()
- else if "0" <= c andalso c <= "9" then ord c - ord "0"
- else if "A" <= c andalso c <= "F" then ord c - ord "A" + 10
- else err ())
- end;
-
-
-(* char *)
-
-val charT = Type ("List.char", []);
-
-fun mk_char n =
- if 0 <= n andalso n <= 255 then
- Const ("List.char.Char", nibbleT --> nibbleT --> charT) $
- mk_nibble (n div 16) $ mk_nibble (n mod 16)
- else raise TERM ("mk_char", []);
-
-fun dest_char (Const ("List.char.Char", _) $ t $ u) =
- dest_nibble t * 16 + dest_nibble u
- | dest_char t = raise TERM ("dest_char", [t]);
-
-
(* list *)
fun listT T = Type ("List.list", [T]);
@@ -570,11 +535,60 @@
| dest_list t = raise TERM ("dest_list", [t]);
+(* nibble *)
+
+val nibbleT = Type ("String.nibble", []);
+
+fun mk_nibble n =
+ let val s =
+ if 0 <= n andalso n <= 9 then chr (n + ord "0")
+ else if 10 <= n andalso n <= 15 then chr (n + ord "A" - 10)
+ else raise TERM ("mk_nibble", [])
+ in Const ("String.nibble.Nibble" ^ s, nibbleT) end;
+
+fun dest_nibble t =
+ let fun err () = raise TERM ("dest_nibble", [t]) in
+ (case try (unprefix "String.nibble.Nibble" o fst o Term.dest_Const) t of
+ NONE => err ()
+ | SOME c =>
+ if size c <> 1 then err ()
+ else if "0" <= c andalso c <= "9" then ord c - ord "0"
+ else if "A" <= c andalso c <= "F" then ord c - ord "A" + 10
+ else err ())
+ end;
+
+
+(* char *)
+
+val charT = Type ("String.char", []);
+
+fun mk_char n =
+ if 0 <= n andalso n <= 255 then
+ Const ("String.char.Char", nibbleT --> nibbleT --> charT) $
+ mk_nibble (n div 16) $ mk_nibble (n mod 16)
+ else raise TERM ("mk_char", []);
+
+fun dest_char (Const ("String.char.Char", _) $ t $ u) =
+ dest_nibble t * 16 + dest_nibble u
+ | dest_char t = raise TERM ("dest_char", [t]);
+
+
(* string *)
-val stringT = Type ("List.string", []);
+val stringT = Type ("String.string", []);
val mk_string = mk_list charT o map (mk_char o ord) o explode;
val dest_string = implode o map (chr o dest_char) o dest_list;
+
+(* message_string *)
+
+val message_stringT = Type ("String.message_string", []);
+
+fun mk_message_string s = Const ("String.message_string.STR", stringT --> message_stringT)
+ $ mk_string s;
+fun dest_message_string (Const ("String.message_string.STR", _) $ t) =
+ dest_string t
+ | dest_message_string t = raise TERM ("dest_message_string", [t]);
+
end;
--- a/src/HOL/Tools/int_arith.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/int_arith.ML Mon May 11 17:20:52 2009 +0200
@@ -1,442 +1,15 @@
-(* Authors: Larry Paulson and Tobias Nipkow
-
-Simprocs and decision procedure for numerals and linear arithmetic.
-*)
-
-structure Int_Numeral_Simprocs =
-struct
-
-(*reorientation simprules using ==, for the following simproc*)
-val meta_zero_reorient = @{thm zero_reorient} RS eq_reflection
-val meta_one_reorient = @{thm one_reorient} RS eq_reflection
-val meta_number_of_reorient = @{thm number_of_reorient} RS eq_reflection
-
-(*reorientation simplification procedure: reorients (polymorphic)
- 0 = x, 1 = x, nnn = x provided x isn't 0, 1 or a Int.*)
-fun reorient_proc sg _ (_ $ t $ u) =
- case u of
- Const(@{const_name HOL.zero}, _) => NONE
- | Const(@{const_name HOL.one}, _) => NONE
- | Const(@{const_name Int.number_of}, _) $ _ => NONE
- | _ => SOME (case t of
- Const(@{const_name HOL.zero}, _) => meta_zero_reorient
- | Const(@{const_name HOL.one}, _) => meta_one_reorient
- | Const(@{const_name Int.number_of}, _) $ _ => meta_number_of_reorient)
-
-val reorient_simproc =
- Arith_Data.prep_simproc ("reorient_simproc", ["0=x", "1=x", "number_of w = x"], reorient_proc);
-
-
-(** Utilities **)
-
-fun mk_number T n = HOLogic.number_of_const T $ HOLogic.mk_numeral n;
-
-fun find_first_numeral past (t::terms) =
- ((snd (HOLogic.dest_number t), rev past @ terms)
- handle TERM _ => find_first_numeral (t::past) terms)
- | find_first_numeral past [] = raise TERM("find_first_numeral", []);
-
-val mk_plus = HOLogic.mk_binop @{const_name HOL.plus};
-
-fun mk_minus t =
- let val T = Term.fastype_of t
- in Const (@{const_name HOL.uminus}, T --> T) $ t end;
-
-(*Thus mk_sum[t] yields t+0; longer sums don't have a trailing zero*)
-fun mk_sum T [] = mk_number T 0
- | mk_sum T [t,u] = mk_plus (t, u)
- | mk_sum T (t :: ts) = mk_plus (t, mk_sum T ts);
-
-(*this version ALWAYS includes a trailing zero*)
-fun long_mk_sum T [] = mk_number T 0
- | long_mk_sum T (t :: ts) = mk_plus (t, mk_sum T ts);
-
-val dest_plus = HOLogic.dest_bin @{const_name HOL.plus} Term.dummyT;
-
-(*decompose additions AND subtractions as a sum*)
-fun dest_summing (pos, Const (@{const_name HOL.plus}, _) $ t $ u, ts) =
- dest_summing (pos, t, dest_summing (pos, u, ts))
- | dest_summing (pos, Const (@{const_name HOL.minus}, _) $ t $ u, ts) =
- dest_summing (pos, t, dest_summing (not pos, u, ts))
- | dest_summing (pos, t, ts) =
- if pos then t::ts else mk_minus t :: ts;
-
-fun dest_sum t = dest_summing (true, t, []);
-
-val mk_diff = HOLogic.mk_binop @{const_name HOL.minus};
-val dest_diff = HOLogic.dest_bin @{const_name HOL.minus} Term.dummyT;
-
-val mk_times = HOLogic.mk_binop @{const_name HOL.times};
-
-fun one_of T = Const(@{const_name HOL.one},T);
-
-(* build product with trailing 1 rather than Numeral 1 in order to avoid the
- unnecessary restriction to type class number_ring
- which is not required for cancellation of common factors in divisions.
-*)
-fun mk_prod T =
- let val one = one_of T
- fun mk [] = one
- | mk [t] = t
- | mk (t :: ts) = if t = one then mk ts else mk_times (t, mk ts)
- in mk end;
-
-(*This version ALWAYS includes a trailing one*)
-fun long_mk_prod T [] = one_of T
- | long_mk_prod T (t :: ts) = mk_times (t, mk_prod T ts);
-
-val dest_times = HOLogic.dest_bin @{const_name HOL.times} Term.dummyT;
-
-fun dest_prod t =
- let val (t,u) = dest_times t
- in dest_prod t @ dest_prod u end
- handle TERM _ => [t];
-
-(*DON'T do the obvious simplifications; that would create special cases*)
-fun mk_coeff (k, t) = mk_times (mk_number (Term.fastype_of t) k, t);
-
-(*Express t as a product of (possibly) a numeral with other sorted terms*)
-fun dest_coeff sign (Const (@{const_name HOL.uminus}, _) $ t) = dest_coeff (~sign) t
- | dest_coeff sign t =
- let val ts = sort TermOrd.term_ord (dest_prod t)
- val (n, ts') = find_first_numeral [] ts
- handle TERM _ => (1, ts)
- in (sign*n, mk_prod (Term.fastype_of t) ts') end;
-
-(*Find first coefficient-term THAT MATCHES u*)
-fun find_first_coeff past u [] = raise TERM("find_first_coeff", [])
- | find_first_coeff past u (t::terms) =
- let val (n,u') = dest_coeff 1 t
- in if u aconv u' then (n, rev past @ terms)
- else find_first_coeff (t::past) u terms
- end
- handle TERM _ => find_first_coeff (t::past) u terms;
-
-(*Fractions as pairs of ints. Can't use Rat.rat because the representation
- needs to preserve negative values in the denominator.*)
-fun mk_frac (p, q) = if q = 0 then raise Div else (p, q);
-
-(*Don't reduce fractions; sums must be proved by rule add_frac_eq.
- Fractions are reduced later by the cancel_numeral_factor simproc.*)
-fun add_frac ((p1, q1), (p2, q2)) = (p1 * q2 + p2 * q1, q1 * q2);
-
-val mk_divide = HOLogic.mk_binop @{const_name HOL.divide};
-
-(*Build term (p / q) * t*)
-fun mk_fcoeff ((p, q), t) =
- let val T = Term.fastype_of t
- in mk_times (mk_divide (mk_number T p, mk_number T q), t) end;
-
-(*Express t as a product of a fraction with other sorted terms*)
-fun dest_fcoeff sign (Const (@{const_name HOL.uminus}, _) $ t) = dest_fcoeff (~sign) t
- | dest_fcoeff sign (Const (@{const_name HOL.divide}, _) $ t $ u) =
- let val (p, t') = dest_coeff sign t
- val (q, u') = dest_coeff 1 u
- in (mk_frac (p, q), mk_divide (t', u')) end
- | dest_fcoeff sign t =
- let val (p, t') = dest_coeff sign t
- val T = Term.fastype_of t
- in (mk_frac (p, 1), mk_divide (t', one_of T)) end;
-
-
-(** New term ordering so that AC-rewriting brings numerals to the front **)
-
-(*Order integers by absolute value and then by sign. The standard integer
- ordering is not well-founded.*)
-fun num_ord (i,j) =
- (case int_ord (abs i, abs j) of
- EQUAL => int_ord (Int.sign i, Int.sign j)
- | ord => ord);
-
-(*This resembles TermOrd.term_ord, but it puts binary numerals before other
- non-atomic terms.*)
-local open Term
-in
-fun numterm_ord (Abs (_, T, t), Abs(_, U, u)) =
- (case numterm_ord (t, u) of EQUAL => TermOrd.typ_ord (T, U) | ord => ord)
- | numterm_ord
- (Const(@{const_name Int.number_of}, _) $ v, Const(@{const_name Int.number_of}, _) $ w) =
- num_ord (HOLogic.dest_numeral v, HOLogic.dest_numeral w)
- | numterm_ord (Const(@{const_name Int.number_of}, _) $ _, _) = LESS
- | numterm_ord (_, Const(@{const_name Int.number_of}, _) $ _) = GREATER
- | numterm_ord (t, u) =
- (case int_ord (size_of_term t, size_of_term u) of
- EQUAL =>
- let val (f, ts) = strip_comb t and (g, us) = strip_comb u in
- (case TermOrd.hd_ord (f, g) of EQUAL => numterms_ord (ts, us) | ord => ord)
- end
- | ord => ord)
-and numterms_ord (ts, us) = list_ord numterm_ord (ts, us)
-end;
-
-fun numtermless tu = (numterm_ord tu = LESS);
-
-val num_ss = HOL_ss settermless numtermless;
-
-(*Maps 0 to Numeral0 and 1 to Numeral1 so that arithmetic isn't complicated by the abstract 0 and 1.*)
-val numeral_syms = [@{thm numeral_0_eq_0} RS sym, @{thm numeral_1_eq_1} RS sym];
-
-(*Simplify Numeral0+n, n+Numeral0, Numeral1*n, n*Numeral1, 1*x, x*1, x/1 *)
-val add_0s = @{thms add_0s};
-val mult_1s = @{thms mult_1s mult_1_left mult_1_right divide_1};
-
-(*Simplify inverse Numeral1, a/Numeral1*)
-val inverse_1s = [@{thm inverse_numeral_1}];
-val divide_1s = [@{thm divide_numeral_1}];
-
-(*To perform binary arithmetic. The "left" rewriting handles patterns
- created by the Int_Numeral_Simprocs, such as 3 * (5 * x). *)
-val simps = [@{thm numeral_0_eq_0} RS sym, @{thm numeral_1_eq_1} RS sym,
- @{thm add_number_of_left}, @{thm mult_number_of_left}] @
- @{thms arith_simps} @ @{thms rel_simps};
-
-(*Binary arithmetic BUT NOT ADDITION since it may collapse adjacent terms
- during re-arrangement*)
-val non_add_simps =
- subtract Thm.eq_thm [@{thm add_number_of_left}, @{thm number_of_add} RS sym] simps;
-
-(*To evaluate binary negations of coefficients*)
-val minus_simps = [@{thm numeral_m1_eq_minus_1} RS sym, @{thm number_of_minus} RS sym] @
- @{thms minus_bin_simps} @ @{thms pred_bin_simps};
-
-(*To let us treat subtraction as addition*)
-val diff_simps = [@{thm diff_minus}, @{thm minus_add_distrib}, @{thm minus_minus}];
-
-(*To let us treat division as multiplication*)
-val divide_simps = [@{thm divide_inverse}, @{thm inverse_mult_distrib}, @{thm inverse_inverse_eq}];
-
-(*push the unary minus down: - x * y = x * - y *)
-val minus_mult_eq_1_to_2 =
- [@{thm mult_minus_left}, @{thm minus_mult_right}] MRS trans |> standard;
-
-(*to extract again any uncancelled minuses*)
-val minus_from_mult_simps =
- [@{thm minus_minus}, @{thm mult_minus_left}, @{thm mult_minus_right}];
+(* Author: Tobias Nipkow
-(*combine unary minus with numeric literals, however nested within a product*)
-val mult_minus_simps =
- [@{thm mult_assoc}, @{thm minus_mult_left}, minus_mult_eq_1_to_2];
-
-val norm_ss1 = num_ss addsimps numeral_syms @ add_0s @ mult_1s @
- diff_simps @ minus_simps @ @{thms add_ac}
-val norm_ss2 = num_ss addsimps non_add_simps @ mult_minus_simps
-val norm_ss3 = num_ss addsimps minus_from_mult_simps @ @{thms add_ac} @ @{thms mult_ac}
-
-structure CancelNumeralsCommon =
- struct
- val mk_sum = mk_sum
- val dest_sum = dest_sum
- val mk_coeff = mk_coeff
- val dest_coeff = dest_coeff 1
- val find_first_coeff = find_first_coeff []
- val trans_tac = K Arith_Data.trans_tac
-
- fun norm_tac ss =
- ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
- THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
- THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
-
- val numeral_simp_ss = HOL_ss addsimps add_0s @ simps
- fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
- val simplify_meta_eq = Arith_Data.simplify_meta_eq (add_0s @ mult_1s)
- end;
-
-
-structure EqCancelNumerals = CancelNumeralsFun
- (open CancelNumeralsCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_eq
- val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
- val bal_add1 = @{thm eq_add_iff1} RS trans
- val bal_add2 = @{thm eq_add_iff2} RS trans
-);
-
-structure LessCancelNumerals = CancelNumeralsFun
- (open CancelNumeralsCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less} Term.dummyT
- val bal_add1 = @{thm less_add_iff1} RS trans
- val bal_add2 = @{thm less_add_iff2} RS trans
-);
-
-structure LeCancelNumerals = CancelNumeralsFun
- (open CancelNumeralsCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} Term.dummyT
- val bal_add1 = @{thm le_add_iff1} RS trans
- val bal_add2 = @{thm le_add_iff2} RS trans
-);
-
-val cancel_numerals =
- map Arith_Data.prep_simproc
- [("inteq_cancel_numerals",
- ["(l::'a::number_ring) + m = n",
- "(l::'a::number_ring) = m + n",
- "(l::'a::number_ring) - m = n",
- "(l::'a::number_ring) = m - n",
- "(l::'a::number_ring) * m = n",
- "(l::'a::number_ring) = m * n"],
- K EqCancelNumerals.proc),
- ("intless_cancel_numerals",
- ["(l::'a::{ordered_idom,number_ring}) + m < n",
- "(l::'a::{ordered_idom,number_ring}) < m + n",
- "(l::'a::{ordered_idom,number_ring}) - m < n",
- "(l::'a::{ordered_idom,number_ring}) < m - n",
- "(l::'a::{ordered_idom,number_ring}) * m < n",
- "(l::'a::{ordered_idom,number_ring}) < m * n"],
- K LessCancelNumerals.proc),
- ("intle_cancel_numerals",
- ["(l::'a::{ordered_idom,number_ring}) + m <= n",
- "(l::'a::{ordered_idom,number_ring}) <= m + n",
- "(l::'a::{ordered_idom,number_ring}) - m <= n",
- "(l::'a::{ordered_idom,number_ring}) <= m - n",
- "(l::'a::{ordered_idom,number_ring}) * m <= n",
- "(l::'a::{ordered_idom,number_ring}) <= m * n"],
- K LeCancelNumerals.proc)];
-
-
-structure CombineNumeralsData =
- struct
- type coeff = int
- val iszero = (fn x => x = 0)
- val add = op +
- val mk_sum = long_mk_sum (*to work for e.g. 2*x + 3*x *)
- val dest_sum = dest_sum
- val mk_coeff = mk_coeff
- val dest_coeff = dest_coeff 1
- val left_distrib = @{thm combine_common_factor} RS trans
- val prove_conv = Arith_Data.prove_conv_nohyps
- val trans_tac = K Arith_Data.trans_tac
-
- fun norm_tac ss =
- ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
- THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
- THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
-
- val numeral_simp_ss = HOL_ss addsimps add_0s @ simps
- fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
- val simplify_meta_eq = Arith_Data.simplify_meta_eq (add_0s @ mult_1s)
- end;
-
-structure CombineNumerals = CombineNumeralsFun(CombineNumeralsData);
-
-(*Version for fields, where coefficients can be fractions*)
-structure FieldCombineNumeralsData =
- struct
- type coeff = int * int
- val iszero = (fn (p, q) => p = 0)
- val add = add_frac
- val mk_sum = long_mk_sum
- val dest_sum = dest_sum
- val mk_coeff = mk_fcoeff
- val dest_coeff = dest_fcoeff 1
- val left_distrib = @{thm combine_common_factor} RS trans
- val prove_conv = Arith_Data.prove_conv_nohyps
- val trans_tac = K Arith_Data.trans_tac
-
- val norm_ss1a = norm_ss1 addsimps inverse_1s @ divide_simps
- fun norm_tac ss =
- ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1a))
- THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
- THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
-
- val numeral_simp_ss = HOL_ss addsimps add_0s @ simps @ [@{thm add_frac_eq}]
- fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
- val simplify_meta_eq = Arith_Data.simplify_meta_eq (add_0s @ mult_1s @ divide_1s)
- end;
-
-structure FieldCombineNumerals = CombineNumeralsFun(FieldCombineNumeralsData);
-
-val combine_numerals =
- Arith_Data.prep_simproc
- ("int_combine_numerals",
- ["(i::'a::number_ring) + j", "(i::'a::number_ring) - j"],
- K CombineNumerals.proc);
-
-val field_combine_numerals =
- Arith_Data.prep_simproc
- ("field_combine_numerals",
- ["(i::'a::{number_ring,field,division_by_zero}) + j",
- "(i::'a::{number_ring,field,division_by_zero}) - j"],
- K FieldCombineNumerals.proc);
-
-(** Constant folding for multiplication in semirings **)
-
-(*We do not need folding for addition: combine_numerals does the same thing*)
-
-structure Semiring_Times_Assoc_Data : ASSOC_FOLD_DATA =
-struct
- val assoc_ss = HOL_ss addsimps @{thms mult_ac}
- val eq_reflection = eq_reflection
- fun is_numeral (Const(@{const_name Int.number_of}, _) $ _) = true
- | is_numeral _ = false;
-end;
-
-structure Semiring_Times_Assoc = Assoc_Fold (Semiring_Times_Assoc_Data);
-
-val assoc_fold_simproc =
- Arith_Data.prep_simproc
- ("semiring_assoc_fold", ["(a::'a::comm_semiring_1_cancel) * b"],
- K Semiring_Times_Assoc.proc);
-
-end;
-
-Addsimprocs [Int_Numeral_Simprocs.reorient_simproc];
-Addsimprocs Int_Numeral_Simprocs.cancel_numerals;
-Addsimprocs [Int_Numeral_Simprocs.combine_numerals];
-Addsimprocs [Int_Numeral_Simprocs.field_combine_numerals];
-Addsimprocs [Int_Numeral_Simprocs.assoc_fold_simproc];
-
-(*examples:
-print_depth 22;
-set timing;
-set trace_simp;
-fun test s = (Goal s, by (Simp_tac 1));
-
-test "l + 2 + 2 + 2 + (l + 2) + (oo + 2) = (uu::int)";
-
-test "2*u = (u::int)";
-test "(i + j + 12 + (k::int)) - 15 = y";
-test "(i + j + 12 + (k::int)) - 5 = y";
-
-test "y - b < (b::int)";
-test "y - (3*b + c) < (b::int) - 2*c";
-
-test "(2*x - (u*v) + y) - v*3*u = (w::int)";
-test "(2*x*u*v + (u*v)*4 + y) - v*u*4 = (w::int)";
-test "(2*x*u*v + (u*v)*4 + y) - v*u = (w::int)";
-test "u*v - (x*u*v + (u*v)*4 + y) = (w::int)";
-
-test "(i + j + 12 + (k::int)) = u + 15 + y";
-test "(i + j*2 + 12 + (k::int)) = j + 5 + y";
-
-test "2*y + 3*z + 6*w + 2*y + 3*z + 2*u = 2*y' + 3*z' + 6*w' + 2*y' + 3*z' + u + (vv::int)";
-
-test "a + -(b+c) + b = (d::int)";
-test "a + -(b+c) - b = (d::int)";
-
-(*negative numerals*)
-test "(i + j + -2 + (k::int)) - (u + 5 + y) = zz";
-test "(i + j + -3 + (k::int)) < u + 5 + y";
-test "(i + j + 3 + (k::int)) < u + -6 + y";
-test "(i + j + -12 + (k::int)) - 15 = y";
-test "(i + j + 12 + (k::int)) - -15 = y";
-test "(i + j + -12 + (k::int)) - -15 = y";
-*)
-
-(*** decision procedure for linear arithmetic ***)
-
-(*---------------------------------------------------------------------------*)
-(* Linear arithmetic *)
-(*---------------------------------------------------------------------------*)
-
-(*
Instantiation of the generic linear arithmetic package for int.
*)
-structure Int_Arith =
+signature INT_ARITH =
+sig
+ val fast_int_arith_simproc: simproc
+ val setup: Context.generic -> Context.generic
+end
+
+structure Int_Arith : INT_ARITH =
struct
(* Update parameters of arithmetic prover *)
@@ -513,22 +86,21 @@
val nat_inj_thms = [@{thm zle_int} RS iffD2, @{thm int_int_eq} RS iffD2]
-val int_numeral_base_simprocs = Int_Numeral_Simprocs.assoc_fold_simproc :: zero_one_idom_simproc
- :: Int_Numeral_Simprocs.combine_numerals
- :: Int_Numeral_Simprocs.cancel_numerals;
+val numeral_base_simprocs = Numeral_Simprocs.assoc_fold_simproc :: zero_one_idom_simproc
+ :: Numeral_Simprocs.combine_numerals
+ :: Numeral_Simprocs.cancel_numerals;
val setup =
Lin_Arith.map_data (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset} =>
{add_mono_thms = add_mono_thms,
- mult_mono_thms = @{thm mult_strict_left_mono} :: @{thm mult_left_mono} :: mult_mono_thms,
+ mult_mono_thms = (*@{thm mult_strict_left_mono} :: @{thm mult_left_mono} :: *)mult_mono_thms,
inj_thms = nat_inj_thms @ inj_thms,
lessD = lessD @ [@{thm zless_imp_add1_zle}],
neqE = neqE,
simpset = simpset addsimps add_rules
- addsimprocs int_numeral_base_simprocs
- addcongs [if_weak_cong]}) #>
- arith_inj_const (@{const_name of_nat}, HOLogic.natT --> HOLogic.intT) #>
- arith_discrete @{type_name Int.int}
+ addsimprocs numeral_base_simprocs}) #>
+ Lin_Arith.add_inj_const (@{const_name of_nat}, HOLogic.natT --> HOLogic.intT) #>
+ Lin_Arith.add_discrete_type @{type_name Int.int}
val fast_int_arith_simproc =
Simplifier.simproc (the_context ())
--- a/src/HOL/Tools/int_factor_simprocs.ML Mon May 11 09:39:53 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,390 +0,0 @@
-(* Title: HOL/int_factor_simprocs.ML
- ID: $Id$
- Author: Lawrence C Paulson, Cambridge University Computer Laboratory
- Copyright 2000 University of Cambridge
-
-Factor cancellation simprocs for the integers (and for fields).
-
-This file can't be combined with int_arith1 because it requires IntDiv.thy.
-*)
-
-
-(*To quote from Provers/Arith/cancel_numeral_factor.ML:
-
-Cancels common coefficients in balanced expressions:
-
- u*#m ~~ u'*#m' == #n*u ~~ #n'*u'
-
-where ~~ is an appropriate balancing operation (e.g. =, <=, <, div, /)
-and d = gcd(m,m') and n=m/d and n'=m'/d.
-*)
-
-val rel_number_of = [@{thm eq_number_of_eq}, @{thm less_number_of}, @{thm le_number_of}];
-
-local
- open Int_Numeral_Simprocs
-in
-
-structure CancelNumeralFactorCommon =
- struct
- val mk_coeff = mk_coeff
- val dest_coeff = dest_coeff 1
- val trans_tac = K Arith_Data.trans_tac
-
- val norm_ss1 = HOL_ss addsimps minus_from_mult_simps @ mult_1s
- val norm_ss2 = HOL_ss addsimps simps @ mult_minus_simps
- val norm_ss3 = HOL_ss addsimps @{thms mult_ac}
- fun norm_tac ss =
- ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
- THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
- THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
-
- val numeral_simp_ss = HOL_ss addsimps rel_number_of @ simps
- fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
- val simplify_meta_eq = Arith_Data.simplify_meta_eq
- [@{thm add_0}, @{thm add_0_right}, @{thm mult_zero_left},
- @{thm mult_zero_right}, @{thm mult_Bit1}, @{thm mult_1_right}];
- end
-
-(*Version for integer division*)
-structure IntDivCancelNumeralFactor = CancelNumeralFactorFun
- (open CancelNumeralFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binop @{const_name Divides.div}
- val dest_bal = HOLogic.dest_bin @{const_name Divides.div} HOLogic.intT
- val cancel = @{thm zdiv_zmult_zmult1} RS trans
- val neg_exchanges = false
-)
-
-(*Version for fields*)
-structure DivideCancelNumeralFactor = CancelNumeralFactorFun
- (open CancelNumeralFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binop @{const_name HOL.divide}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.divide} Term.dummyT
- val cancel = @{thm mult_divide_mult_cancel_left} RS trans
- val neg_exchanges = false
-)
-
-structure EqCancelNumeralFactor = CancelNumeralFactorFun
- (open CancelNumeralFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_eq
- val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
- val cancel = @{thm mult_cancel_left} RS trans
- val neg_exchanges = false
-)
-
-structure LessCancelNumeralFactor = CancelNumeralFactorFun
- (open CancelNumeralFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less} Term.dummyT
- val cancel = @{thm mult_less_cancel_left} RS trans
- val neg_exchanges = true
-)
-
-structure LeCancelNumeralFactor = CancelNumeralFactorFun
- (open CancelNumeralFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} Term.dummyT
- val cancel = @{thm mult_le_cancel_left} RS trans
- val neg_exchanges = true
-)
-
-val cancel_numeral_factors =
- map Arith_Data.prep_simproc
- [("ring_eq_cancel_numeral_factor",
- ["(l::'a::{idom,number_ring}) * m = n",
- "(l::'a::{idom,number_ring}) = m * n"],
- K EqCancelNumeralFactor.proc),
- ("ring_less_cancel_numeral_factor",
- ["(l::'a::{ordered_idom,number_ring}) * m < n",
- "(l::'a::{ordered_idom,number_ring}) < m * n"],
- K LessCancelNumeralFactor.proc),
- ("ring_le_cancel_numeral_factor",
- ["(l::'a::{ordered_idom,number_ring}) * m <= n",
- "(l::'a::{ordered_idom,number_ring}) <= m * n"],
- K LeCancelNumeralFactor.proc),
- ("int_div_cancel_numeral_factors",
- ["((l::int) * m) div n", "(l::int) div (m * n)"],
- K IntDivCancelNumeralFactor.proc),
- ("divide_cancel_numeral_factor",
- ["((l::'a::{division_by_zero,field,number_ring}) * m) / n",
- "(l::'a::{division_by_zero,field,number_ring}) / (m * n)",
- "((number_of v)::'a::{division_by_zero,field,number_ring}) / (number_of w)"],
- K DivideCancelNumeralFactor.proc)];
-
-(* referenced by rat_arith.ML *)
-val field_cancel_numeral_factors =
- map Arith_Data.prep_simproc
- [("field_eq_cancel_numeral_factor",
- ["(l::'a::{field,number_ring}) * m = n",
- "(l::'a::{field,number_ring}) = m * n"],
- K EqCancelNumeralFactor.proc),
- ("field_cancel_numeral_factor",
- ["((l::'a::{division_by_zero,field,number_ring}) * m) / n",
- "(l::'a::{division_by_zero,field,number_ring}) / (m * n)",
- "((number_of v)::'a::{division_by_zero,field,number_ring}) / (number_of w)"],
- K DivideCancelNumeralFactor.proc)]
-
-end;
-
-Addsimprocs cancel_numeral_factors;
-
-(*examples:
-print_depth 22;
-set timing;
-set trace_simp;
-fun test s = (Goal s; by (Simp_tac 1));
-
-test "9*x = 12 * (y::int)";
-test "(9*x) div (12 * (y::int)) = z";
-test "9*x < 12 * (y::int)";
-test "9*x <= 12 * (y::int)";
-
-test "-99*x = 132 * (y::int)";
-test "(-99*x) div (132 * (y::int)) = z";
-test "-99*x < 132 * (y::int)";
-test "-99*x <= 132 * (y::int)";
-
-test "999*x = -396 * (y::int)";
-test "(999*x) div (-396 * (y::int)) = z";
-test "999*x < -396 * (y::int)";
-test "999*x <= -396 * (y::int)";
-
-test "-99*x = -81 * (y::int)";
-test "(-99*x) div (-81 * (y::int)) = z";
-test "-99*x <= -81 * (y::int)";
-test "-99*x < -81 * (y::int)";
-
-test "-2 * x = -1 * (y::int)";
-test "-2 * x = -(y::int)";
-test "(-2 * x) div (-1 * (y::int)) = z";
-test "-2 * x < -(y::int)";
-test "-2 * x <= -1 * (y::int)";
-test "-x < -23 * (y::int)";
-test "-x <= -23 * (y::int)";
-*)
-
-(*And the same examples for fields such as rat or real:
-test "0 <= (y::rat) * -2";
-test "9*x = 12 * (y::rat)";
-test "(9*x) / (12 * (y::rat)) = z";
-test "9*x < 12 * (y::rat)";
-test "9*x <= 12 * (y::rat)";
-
-test "-99*x = 132 * (y::rat)";
-test "(-99*x) / (132 * (y::rat)) = z";
-test "-99*x < 132 * (y::rat)";
-test "-99*x <= 132 * (y::rat)";
-
-test "999*x = -396 * (y::rat)";
-test "(999*x) / (-396 * (y::rat)) = z";
-test "999*x < -396 * (y::rat)";
-test "999*x <= -396 * (y::rat)";
-
-test "(- ((2::rat) * x) <= 2 * y)";
-test "-99*x = -81 * (y::rat)";
-test "(-99*x) / (-81 * (y::rat)) = z";
-test "-99*x <= -81 * (y::rat)";
-test "-99*x < -81 * (y::rat)";
-
-test "-2 * x = -1 * (y::rat)";
-test "-2 * x = -(y::rat)";
-test "(-2 * x) / (-1 * (y::rat)) = z";
-test "-2 * x < -(y::rat)";
-test "-2 * x <= -1 * (y::rat)";
-test "-x < -23 * (y::rat)";
-test "-x <= -23 * (y::rat)";
-*)
-
-
-(** Declarations for ExtractCommonTerm **)
-
-local
- open Int_Numeral_Simprocs
-in
-
-(*Find first term that matches u*)
-fun find_first_t past u [] = raise TERM ("find_first_t", [])
- | find_first_t past u (t::terms) =
- if u aconv t then (rev past @ terms)
- else find_first_t (t::past) u terms
- handle TERM _ => find_first_t (t::past) u terms;
-
-(** Final simplification for the CancelFactor simprocs **)
-val simplify_one = Arith_Data.simplify_meta_eq
- [@{thm mult_1_left}, @{thm mult_1_right}, @{thm div_by_1}, @{thm numeral_1_eq_1}];
-
-fun cancel_simplify_meta_eq ss cancel_th th =
- simplify_one ss (([th, cancel_th]) MRS trans);
-
-local
- val Tp_Eq = Thm.reflexive(Thm.cterm_of (@{theory HOL}) HOLogic.Trueprop)
- fun Eq_True_elim Eq =
- Thm.equal_elim (Thm.combination Tp_Eq (Thm.symmetric Eq)) @{thm TrueI}
-in
-fun sign_conv pos_th neg_th ss t =
- let val T = fastype_of t;
- val zero = Const(@{const_name HOL.zero}, T);
- val less = Const(@{const_name HOL.less}, [T,T] ---> HOLogic.boolT);
- val pos = less $ zero $ t and neg = less $ t $ zero
- fun prove p =
- Option.map Eq_True_elim (Lin_Arith.lin_arith_simproc ss p)
- handle THM _ => NONE
- in case prove pos of
- SOME th => SOME(th RS pos_th)
- | NONE => (case prove neg of
- SOME th => SOME(th RS neg_th)
- | NONE => NONE)
- end;
-end
-
-structure CancelFactorCommon =
- struct
- val mk_sum = long_mk_prod
- val dest_sum = dest_prod
- val mk_coeff = mk_coeff
- val dest_coeff = dest_coeff
- val find_first = find_first_t []
- val trans_tac = K Arith_Data.trans_tac
- val norm_ss = HOL_ss addsimps mult_1s @ @{thms mult_ac}
- fun norm_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss))
- val simplify_meta_eq = cancel_simplify_meta_eq
- end;
-
-(*mult_cancel_left requires a ring with no zero divisors.*)
-structure EqCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_eq
- val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
- val simp_conv = K (K (SOME @{thm mult_cancel_left}))
-);
-
-(*for ordered rings*)
-structure LeCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} Term.dummyT
- val simp_conv = sign_conv
- @{thm mult_le_cancel_left_pos} @{thm mult_le_cancel_left_neg}
-);
-
-(*for ordered rings*)
-structure LessCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less} Term.dummyT
- val simp_conv = sign_conv
- @{thm mult_less_cancel_left_pos} @{thm mult_less_cancel_left_neg}
-);
-
-(*zdiv_zmult_zmult1_if is for integer division (div).*)
-structure IntDivCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binop @{const_name Divides.div}
- val dest_bal = HOLogic.dest_bin @{const_name Divides.div} HOLogic.intT
- val simp_conv = K (K (SOME @{thm zdiv_zmult_zmult1_if}))
-);
-
-structure IntModCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binop @{const_name Divides.mod}
- val dest_bal = HOLogic.dest_bin @{const_name Divides.mod} HOLogic.intT
- val simp_conv = K (K (SOME @{thm zmod_zmult_zmult1}))
-);
-
-structure IntDvdCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name Ring_and_Field.dvd}
- val dest_bal = HOLogic.dest_bin @{const_name Ring_and_Field.dvd} Term.dummyT
- val simp_conv = K (K (SOME @{thm dvd_mult_cancel_left}))
-);
-
-(*Version for all fields, including unordered ones (type complex).*)
-structure DivideCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binop @{const_name HOL.divide}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.divide} Term.dummyT
- val simp_conv = K (K (SOME @{thm mult_divide_mult_cancel_left_if}))
-);
-
-val cancel_factors =
- map Arith_Data.prep_simproc
- [("ring_eq_cancel_factor",
- ["(l::'a::{idom}) * m = n",
- "(l::'a::{idom}) = m * n"],
- K EqCancelFactor.proc),
- ("ordered_ring_le_cancel_factor",
- ["(l::'a::ordered_ring) * m <= n",
- "(l::'a::ordered_ring) <= m * n"],
- K LeCancelFactor.proc),
- ("ordered_ring_less_cancel_factor",
- ["(l::'a::ordered_ring) * m < n",
- "(l::'a::ordered_ring) < m * n"],
- K LessCancelFactor.proc),
- ("int_div_cancel_factor",
- ["((l::int) * m) div n", "(l::int) div (m * n)"],
- K IntDivCancelFactor.proc),
- ("int_mod_cancel_factor",
- ["((l::int) * m) mod n", "(l::int) mod (m * n)"],
- K IntModCancelFactor.proc),
- ("dvd_cancel_factor",
- ["((l::'a::idom) * m) dvd n", "(l::'a::idom) dvd (m * n)"],
- K IntDvdCancelFactor.proc),
- ("divide_cancel_factor",
- ["((l::'a::{division_by_zero,field}) * m) / n",
- "(l::'a::{division_by_zero,field}) / (m * n)"],
- K DivideCancelFactor.proc)];
-
-end;
-
-Addsimprocs cancel_factors;
-
-
-(*examples:
-print_depth 22;
-set timing;
-set trace_simp;
-fun test s = (Goal s; by (Asm_simp_tac 1));
-
-test "x*k = k*(y::int)";
-test "k = k*(y::int)";
-test "a*(b*c) = (b::int)";
-test "a*(b*c) = d*(b::int)*(x*a)";
-
-test "(x*k) div (k*(y::int)) = (uu::int)";
-test "(k) div (k*(y::int)) = (uu::int)";
-test "(a*(b*c)) div ((b::int)) = (uu::int)";
-test "(a*(b*c)) div (d*(b::int)*(x*a)) = (uu::int)";
-*)
-
-(*And the same examples for fields such as rat or real:
-print_depth 22;
-set timing;
-set trace_simp;
-fun test s = (Goal s; by (Asm_simp_tac 1));
-
-test "x*k = k*(y::rat)";
-test "k = k*(y::rat)";
-test "a*(b*c) = (b::rat)";
-test "a*(b*c) = d*(b::rat)*(x*a)";
-
-
-test "(x*k) / (k*(y::rat)) = (uu::rat)";
-test "(k) / (k*(y::rat)) = (uu::rat)";
-test "(a*(b*c)) / ((b::rat)) = (uu::rat)";
-test "(a*(b*c)) / (d*(b::rat)*(x*a)) = (uu::rat)";
-
-(*FIXME: what do we do about this?*)
-test "a*(b*c)/(y*z) = d*(b::rat)*(x*a)/z";
-*)
--- a/src/HOL/Tools/lin_arith.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/lin_arith.ML Mon May 11 17:20:52 2009 +0200
@@ -7,14 +7,9 @@
signature BASIC_LIN_ARITH =
sig
val arith_split_add: attribute
- val arith_discrete: string -> Context.generic -> Context.generic
- val arith_inj_const: string * typ -> Context.generic -> Context.generic
- val fast_arith_split_limit: int Config.T
- val fast_arith_neq_limit: int Config.T
val lin_arith_pre_tac: Proof.context -> int -> tactic
val fast_arith_tac: Proof.context -> int -> tactic
val fast_ex_arith_tac: Proof.context -> bool -> int -> tactic
- val trace_arith: bool ref
val lin_arith_simproc: simpset -> term -> thm option
val fast_nat_arith_simproc: simproc
val linear_arith_tac: Proof.context -> int -> tactic
@@ -23,14 +18,19 @@
signature LIN_ARITH =
sig
include BASIC_LIN_ARITH
+ val add_discrete_type: string -> Context.generic -> Context.generic
+ val add_inj_const: string * typ -> Context.generic -> Context.generic
val map_data:
({add_mono_thms: thm list, mult_mono_thms: thm list, inj_thms: thm list,
lessD: thm list, neqE: thm list, simpset: Simplifier.simpset} ->
{add_mono_thms: thm list, mult_mono_thms: thm list, inj_thms: thm list,
lessD: thm list, neqE: thm list, simpset: Simplifier.simpset}) ->
Context.generic -> Context.generic
+ val setup: Context.generic -> Context.generic
+ val split_limit: int Config.T
+ val neq_limit: int Config.T
val warning_count: int ref
- val setup: Context.generic -> Context.generic
+ val trace: bool ref
end;
structure Lin_Arith: LIN_ARITH =
@@ -99,23 +99,23 @@
{splits = update Thm.eq_thm_prop thm splits,
inj_consts = inj_consts, discrete = discrete}));
-fun arith_discrete d = ArithContextData.map (fn {splits, inj_consts, discrete} =>
+fun add_discrete_type d = ArithContextData.map (fn {splits, inj_consts, discrete} =>
{splits = splits, inj_consts = inj_consts,
discrete = update (op =) d discrete});
-fun arith_inj_const c = ArithContextData.map (fn {splits, inj_consts, discrete} =>
+fun add_inj_const c = ArithContextData.map (fn {splits, inj_consts, discrete} =>
{splits = splits, inj_consts = update (op =) c inj_consts,
discrete = discrete});
-val (fast_arith_split_limit, setup1) = Attrib.config_int "fast_arith_split_limit" 9;
-val (fast_arith_neq_limit, setup2) = Attrib.config_int "fast_arith_neq_limit" 9;
+val (split_limit, setup1) = Attrib.config_int "linarith_split_limit" 9;
+val (neq_limit, setup2) = Attrib.config_int "linarith_neq_limit" 9;
val setup_options = setup1 #> setup2;
structure LA_Data_Ref =
struct
-val fast_arith_neq_limit = fast_arith_neq_limit;
+val fast_arith_neq_limit = neq_limit;
(* Decomposition of terms *)
@@ -358,10 +358,10 @@
val split_thms = filter is_split_thm (#splits (get_arith_data ctxt))
val cmap = Splitter.cmap_of_split_thms split_thms
val splits = Splitter.split_posns cmap thy Ts (REPEAT_DETERM_etac_rev_mp terms)
- val split_limit = Config.get ctxt fast_arith_split_limit
+ val split_limit = Config.get ctxt split_limit
in
if length splits > split_limit then
- (tracing ("fast_arith_split_limit exceeded (current value is " ^
+ (tracing ("linarith_split_limit exceeded (current value is " ^
string_of_int split_limit ^ ")"); NONE)
else (
case splits of [] =>
@@ -696,7 +696,7 @@
(* disjunctions and existential quantifiers from the premises, possibly (in *)
(* the case of disjunctions) resulting in several new subgoals, each of the *)
(* general form [| Q1; ...; Qm |] ==> False. Fails if more than *)
-(* !fast_arith_split_limit splits are possible. *)
+(* !split_limit splits are possible. *)
local
val nnf_simpset =
@@ -717,7 +717,7 @@
val concl = HOLogic.dest_Trueprop (Logic.strip_assums_concl subgoal)
val cmap = Splitter.cmap_of_split_thms split_thms
val splits = Splitter.split_posns cmap thy Ts concl
- val split_limit = Config.get ctxt fast_arith_split_limit
+ val split_limit = Config.get ctxt split_limit
in
if length splits > split_limit then no_tac
else split_tac split_thms i
@@ -767,7 +767,7 @@
fun fast_arith_tac ctxt = Fast_Arith.lin_arith_tac ctxt false;
val fast_ex_arith_tac = Fast_Arith.lin_arith_tac;
-val trace_arith = Fast_Arith.trace;
+val trace = Fast_Arith.trace;
val warning_count = Fast_Arith.warning_count;
(* reduce contradictory <= to False.
@@ -775,11 +775,10 @@
val init_arith_data =
map_data (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, ...} =>
- {add_mono_thms = add_mono_thms @
- @{thms add_mono_thms_ordered_semiring} @ @{thms add_mono_thms_ordered_field},
- mult_mono_thms = mult_mono_thms,
+ {add_mono_thms = @{thms add_mono_thms_ordered_semiring} @ @{thms add_mono_thms_ordered_field} @ add_mono_thms,
+ mult_mono_thms = @{thm mult_strict_left_mono} :: @{thm mult_left_mono} :: mult_mono_thms,
inj_thms = inj_thms,
- lessD = lessD @ [thm "Suc_leI"],
+ lessD = lessD @ [@{thm "Suc_leI"}],
neqE = [@{thm linorder_neqE_nat}, @{thm linorder_neqE_ordered_idom}],
simpset = HOL_basic_ss
addsimps
@@ -791,8 +790,9 @@
@{thm "not_one_less_zero"}]
addsimprocs [ab_group_add_cancel.sum_conv, ab_group_add_cancel.rel_conv]
(*abel_cancel helps it work in abstract algebraic domains*)
- addsimprocs Nat_Arith.nat_cancel_sums_add}) #>
- arith_discrete "nat";
+ addsimprocs Nat_Arith.nat_cancel_sums_add
+ addcongs [if_weak_cong]}) #>
+ add_discrete_type @{type_name nat};
fun add_arith_facts ss =
add_prems (Arith_Data.get_arith_facts (MetaSimplifier.the_context ss)) ss;
@@ -869,7 +869,7 @@
(* Splitting is also done inside fast_arith_tac, but not completely -- *)
(* split_tac may use split theorems that have not been implemented in *)
(* fast_arith_tac (cf. pre_decomp and split_once_items above), and *)
- (* fast_arith_split_limit may trigger. *)
+ (* split_limit may trigger. *)
(* Therefore splitting outside of fast_arith_tac may allow us to prove *)
(* some goals that fast_arith_tac alone would fail on. *)
(REPEAT_DETERM o split_tac (#splits (get_arith_data ctxt)))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Tools/list_code.ML Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,52 @@
+(* Author: Florian Haftmann, TU Muenchen
+
+Code generation for list literals.
+*)
+
+signature LIST_CODE =
+sig
+ val implode_list: string -> string -> Code_Thingol.iterm -> Code_Thingol.iterm list option
+ val default_list: int * string
+ -> (Code_Printer.fixity -> Code_Thingol.iterm -> Pretty.T)
+ -> Code_Printer.fixity -> Code_Thingol.iterm -> Code_Thingol.iterm -> Pretty.T
+ val add_literal_list: string -> theory -> theory
+end;
+
+structure List_Code : LIST_CODE =
+struct
+
+open Basic_Code_Thingol;
+
+fun implode_list nil' cons' t =
+ let
+ fun dest_cons (IConst (c, _) `$ t1 `$ t2) =
+ if c = cons'
+ then SOME (t1, t2)
+ else NONE
+ | dest_cons _ = NONE;
+ val (ts, t') = Code_Thingol.unfoldr dest_cons t;
+ in case t'
+ of IConst (c, _) => if c = nil' then SOME ts else NONE
+ | _ => NONE
+ end;
+
+fun default_list (target_fxy, target_cons) pr fxy t1 t2 =
+ Code_Printer.brackify_infix (target_fxy, Code_Printer.R) fxy [
+ pr (Code_Printer.INFX (target_fxy, Code_Printer.X)) t1,
+ Code_Printer.str target_cons,
+ pr (Code_Printer.INFX (target_fxy, Code_Printer.R)) t2
+ ];
+
+fun add_literal_list target =
+ let
+ fun pretty literals [nil', cons'] pr thm vars fxy [(t1, _), (t2, _)] =
+ case Option.map (cons t1) (implode_list nil' cons' t2)
+ of SOME ts =>
+ Code_Printer.literal_list literals (map (pr vars Code_Printer.NOBR) ts)
+ | NONE =>
+ default_list (Code_Printer.infix_cons literals) (pr vars) fxy t1 t2;
+ in Code_Target.add_syntax_const target
+ @{const_name Cons} (SOME (2, ([@{const_name Nil}, @{const_name Cons}], pretty)))
+ end
+
+end;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Tools/nat_numeral_simprocs.ML Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,538 @@
+(* Author: Lawrence C Paulson, Cambridge University Computer Laboratory
+
+Simprocs for nat numerals.
+*)
+
+signature NAT_NUMERAL_SIMPROCS =
+sig
+ val combine_numerals: simproc
+ val cancel_numerals: simproc list
+ val cancel_factors: simproc list
+ val cancel_numeral_factors: simproc list
+end;
+
+structure Nat_Numeral_Simprocs =
+struct
+
+(*Maps n to #n for n = 0, 1, 2*)
+val numeral_syms = [@{thm nat_numeral_0_eq_0} RS sym, @{thm nat_numeral_1_eq_1} RS sym, @{thm numeral_2_eq_2} RS sym];
+val numeral_sym_ss = HOL_ss addsimps numeral_syms;
+
+fun rename_numerals th =
+ simplify numeral_sym_ss (Thm.transfer (the_context ()) th);
+
+(*Utilities*)
+
+fun mk_number n = HOLogic.number_of_const HOLogic.natT $ HOLogic.mk_numeral n;
+fun dest_number t = Int.max (0, snd (HOLogic.dest_number t));
+
+fun find_first_numeral past (t::terms) =
+ ((dest_number t, t, rev past @ terms)
+ handle TERM _ => find_first_numeral (t::past) terms)
+ | find_first_numeral past [] = raise TERM("find_first_numeral", []);
+
+val zero = mk_number 0;
+val mk_plus = HOLogic.mk_binop @{const_name HOL.plus};
+
+(*Thus mk_sum[t] yields t+0; longer sums don't have a trailing zero*)
+fun mk_sum [] = zero
+ | mk_sum [t,u] = mk_plus (t, u)
+ | mk_sum (t :: ts) = mk_plus (t, mk_sum ts);
+
+(*this version ALWAYS includes a trailing zero*)
+fun long_mk_sum [] = HOLogic.zero
+ | long_mk_sum (t :: ts) = mk_plus (t, mk_sum ts);
+
+val dest_plus = HOLogic.dest_bin @{const_name HOL.plus} HOLogic.natT;
+
+
+(** Other simproc items **)
+
+val bin_simps =
+ [@{thm nat_numeral_0_eq_0} RS sym, @{thm nat_numeral_1_eq_1} RS sym,
+ @{thm add_nat_number_of}, @{thm nat_number_of_add_left},
+ @{thm diff_nat_number_of}, @{thm le_number_of_eq_not_less},
+ @{thm mult_nat_number_of}, @{thm nat_number_of_mult_left},
+ @{thm less_nat_number_of},
+ @{thm Let_number_of}, @{thm nat_number_of}] @
+ @{thms arith_simps} @ @{thms rel_simps} @ @{thms neg_simps};
+
+
+(*** CancelNumerals simprocs ***)
+
+val one = mk_number 1;
+val mk_times = HOLogic.mk_binop @{const_name HOL.times};
+
+fun mk_prod [] = one
+ | mk_prod [t] = t
+ | mk_prod (t :: ts) = if t = one then mk_prod ts
+ else mk_times (t, mk_prod ts);
+
+val dest_times = HOLogic.dest_bin @{const_name HOL.times} HOLogic.natT;
+
+fun dest_prod t =
+ let val (t,u) = dest_times t
+ in dest_prod t @ dest_prod u end
+ handle TERM _ => [t];
+
+(*DON'T do the obvious simplifications; that would create special cases*)
+fun mk_coeff (k,t) = mk_times (mk_number k, t);
+
+(*Express t as a product of (possibly) a numeral with other factors, sorted*)
+fun dest_coeff t =
+ let val ts = sort TermOrd.term_ord (dest_prod t)
+ val (n, _, ts') = find_first_numeral [] ts
+ handle TERM _ => (1, one, ts)
+ in (n, mk_prod ts') end;
+
+(*Find first coefficient-term THAT MATCHES u*)
+fun find_first_coeff past u [] = raise TERM("find_first_coeff", [])
+ | find_first_coeff past u (t::terms) =
+ let val (n,u') = dest_coeff t
+ in if u aconv u' then (n, rev past @ terms)
+ else find_first_coeff (t::past) u terms
+ end
+ handle TERM _ => find_first_coeff (t::past) u terms;
+
+
+(*Split up a sum into the list of its constituent terms, on the way removing any
+ Sucs and counting them.*)
+fun dest_Suc_sum (Const ("Suc", _) $ t, (k,ts)) = dest_Suc_sum (t, (k+1,ts))
+ | dest_Suc_sum (t, (k,ts)) =
+ let val (t1,t2) = dest_plus t
+ in dest_Suc_sum (t1, dest_Suc_sum (t2, (k,ts))) end
+ handle TERM _ => (k, t::ts);
+
+(*Code for testing whether numerals are already used in the goal*)
+fun is_numeral (Const(@{const_name Int.number_of}, _) $ w) = true
+ | is_numeral _ = false;
+
+fun prod_has_numeral t = exists is_numeral (dest_prod t);
+
+(*The Sucs found in the term are converted to a binary numeral. If relaxed is false,
+ an exception is raised unless the original expression contains at least one
+ numeral in a coefficient position. This prevents nat_combine_numerals from
+ introducing numerals to goals.*)
+fun dest_Sucs_sum relaxed t =
+ let val (k,ts) = dest_Suc_sum (t,(0,[]))
+ in
+ if relaxed orelse exists prod_has_numeral ts then
+ if k=0 then ts
+ else mk_number k :: ts
+ else raise TERM("Nat_Numeral_Simprocs.dest_Sucs_sum", [t])
+ end;
+
+
+(*Simplify 1*n and n*1 to n*)
+val add_0s = map rename_numerals [@{thm add_0}, @{thm add_0_right}];
+val mult_1s = map rename_numerals [@{thm nat_mult_1}, @{thm nat_mult_1_right}];
+
+(*Final simplification: cancel + and *; replace Numeral0 by 0 and Numeral1 by 1*)
+
+(*And these help the simproc return False when appropriate, which helps
+ the arith prover.*)
+val contra_rules = [@{thm add_Suc}, @{thm add_Suc_right}, @{thm Zero_not_Suc},
+ @{thm Suc_not_Zero}, @{thm le_0_eq}];
+
+val simplify_meta_eq =
+ Arith_Data.simplify_meta_eq
+ ([@{thm nat_numeral_0_eq_0}, @{thm numeral_1_eq_Suc_0}, @{thm add_0}, @{thm add_0_right},
+ @{thm mult_0}, @{thm mult_0_right}, @{thm mult_1}, @{thm mult_1_right}] @ contra_rules);
+
+
+(*** Applying CancelNumeralsFun ***)
+
+structure CancelNumeralsCommon =
+ struct
+ val mk_sum = (fn T:typ => mk_sum)
+ val dest_sum = dest_Sucs_sum true
+ val mk_coeff = mk_coeff
+ val dest_coeff = dest_coeff
+ val find_first_coeff = find_first_coeff []
+ val trans_tac = K Arith_Data.trans_tac
+
+ val norm_ss1 = Numeral_Simprocs.num_ss addsimps numeral_syms @ add_0s @ mult_1s @
+ [@{thm Suc_eq_add_numeral_1_left}] @ @{thms add_ac}
+ val norm_ss2 = Numeral_Simprocs.num_ss addsimps bin_simps @ @{thms add_ac} @ @{thms mult_ac}
+ fun norm_tac ss =
+ ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
+ THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
+
+ val numeral_simp_ss = HOL_ss addsimps add_0s @ bin_simps;
+ fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss));
+ val simplify_meta_eq = simplify_meta_eq
+ end;
+
+
+structure EqCancelNumerals = CancelNumeralsFun
+ (open CancelNumeralsCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_eq
+ val dest_bal = HOLogic.dest_bin "op =" HOLogic.natT
+ val bal_add1 = @{thm nat_eq_add_iff1} RS trans
+ val bal_add2 = @{thm nat_eq_add_iff2} RS trans
+);
+
+structure LessCancelNumerals = CancelNumeralsFun
+ (open CancelNumeralsCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less} HOLogic.natT
+ val bal_add1 = @{thm nat_less_add_iff1} RS trans
+ val bal_add2 = @{thm nat_less_add_iff2} RS trans
+);
+
+structure LeCancelNumerals = CancelNumeralsFun
+ (open CancelNumeralsCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} HOLogic.natT
+ val bal_add1 = @{thm nat_le_add_iff1} RS trans
+ val bal_add2 = @{thm nat_le_add_iff2} RS trans
+);
+
+structure DiffCancelNumerals = CancelNumeralsFun
+ (open CancelNumeralsCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binop @{const_name HOL.minus}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.minus} HOLogic.natT
+ val bal_add1 = @{thm nat_diff_add_eq1} RS trans
+ val bal_add2 = @{thm nat_diff_add_eq2} RS trans
+);
+
+
+val cancel_numerals =
+ map Arith_Data.prep_simproc
+ [("nateq_cancel_numerals",
+ ["(l::nat) + m = n", "(l::nat) = m + n",
+ "(l::nat) * m = n", "(l::nat) = m * n",
+ "Suc m = n", "m = Suc n"],
+ K EqCancelNumerals.proc),
+ ("natless_cancel_numerals",
+ ["(l::nat) + m < n", "(l::nat) < m + n",
+ "(l::nat) * m < n", "(l::nat) < m * n",
+ "Suc m < n", "m < Suc n"],
+ K LessCancelNumerals.proc),
+ ("natle_cancel_numerals",
+ ["(l::nat) + m <= n", "(l::nat) <= m + n",
+ "(l::nat) * m <= n", "(l::nat) <= m * n",
+ "Suc m <= n", "m <= Suc n"],
+ K LeCancelNumerals.proc),
+ ("natdiff_cancel_numerals",
+ ["((l::nat) + m) - n", "(l::nat) - (m + n)",
+ "(l::nat) * m - n", "(l::nat) - m * n",
+ "Suc m - n", "m - Suc n"],
+ K DiffCancelNumerals.proc)];
+
+
+(*** Applying CombineNumeralsFun ***)
+
+structure CombineNumeralsData =
+ struct
+ type coeff = int
+ val iszero = (fn x => x = 0)
+ val add = op +
+ val mk_sum = (fn T:typ => long_mk_sum) (*to work for 2*x + 3*x *)
+ val dest_sum = dest_Sucs_sum false
+ val mk_coeff = mk_coeff
+ val dest_coeff = dest_coeff
+ val left_distrib = @{thm left_add_mult_distrib} RS trans
+ val prove_conv = Arith_Data.prove_conv_nohyps
+ val trans_tac = K Arith_Data.trans_tac
+
+ val norm_ss1 = Numeral_Simprocs.num_ss addsimps numeral_syms @ add_0s @ mult_1s @ [@{thm Suc_eq_add_numeral_1}] @ @{thms add_ac}
+ val norm_ss2 = Numeral_Simprocs.num_ss addsimps bin_simps @ @{thms add_ac} @ @{thms mult_ac}
+ fun norm_tac ss =
+ ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
+ THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
+
+ val numeral_simp_ss = HOL_ss addsimps add_0s @ bin_simps;
+ fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
+ val simplify_meta_eq = simplify_meta_eq
+ end;
+
+structure CombineNumerals = CombineNumeralsFun(CombineNumeralsData);
+
+val combine_numerals =
+ Arith_Data.prep_simproc ("nat_combine_numerals", ["(i::nat) + j", "Suc (i + j)"], K CombineNumerals.proc);
+
+
+(*** Applying CancelNumeralFactorFun ***)
+
+structure CancelNumeralFactorCommon =
+ struct
+ val mk_coeff = mk_coeff
+ val dest_coeff = dest_coeff
+ val trans_tac = K Arith_Data.trans_tac
+
+ val norm_ss1 = Numeral_Simprocs.num_ss addsimps
+ numeral_syms @ add_0s @ mult_1s @ [@{thm Suc_eq_add_numeral_1_left}] @ @{thms add_ac}
+ val norm_ss2 = Numeral_Simprocs.num_ss addsimps bin_simps @ @{thms add_ac} @ @{thms mult_ac}
+ fun norm_tac ss =
+ ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
+ THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
+
+ val numeral_simp_ss = HOL_ss addsimps bin_simps
+ fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
+ val simplify_meta_eq = simplify_meta_eq
+ end
+
+structure DivCancelNumeralFactor = CancelNumeralFactorFun
+ (open CancelNumeralFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binop @{const_name Divides.div}
+ val dest_bal = HOLogic.dest_bin @{const_name Divides.div} HOLogic.natT
+ val cancel = @{thm nat_mult_div_cancel1} RS trans
+ val neg_exchanges = false
+)
+
+structure DvdCancelNumeralFactor = CancelNumeralFactorFun
+ (open CancelNumeralFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name Ring_and_Field.dvd}
+ val dest_bal = HOLogic.dest_bin @{const_name Ring_and_Field.dvd} HOLogic.natT
+ val cancel = @{thm nat_mult_dvd_cancel1} RS trans
+ val neg_exchanges = false
+)
+
+structure EqCancelNumeralFactor = CancelNumeralFactorFun
+ (open CancelNumeralFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_eq
+ val dest_bal = HOLogic.dest_bin "op =" HOLogic.natT
+ val cancel = @{thm nat_mult_eq_cancel1} RS trans
+ val neg_exchanges = false
+)
+
+structure LessCancelNumeralFactor = CancelNumeralFactorFun
+ (open CancelNumeralFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less} HOLogic.natT
+ val cancel = @{thm nat_mult_less_cancel1} RS trans
+ val neg_exchanges = true
+)
+
+structure LeCancelNumeralFactor = CancelNumeralFactorFun
+ (open CancelNumeralFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} HOLogic.natT
+ val cancel = @{thm nat_mult_le_cancel1} RS trans
+ val neg_exchanges = true
+)
+
+val cancel_numeral_factors =
+ map Arith_Data.prep_simproc
+ [("nateq_cancel_numeral_factors",
+ ["(l::nat) * m = n", "(l::nat) = m * n"],
+ K EqCancelNumeralFactor.proc),
+ ("natless_cancel_numeral_factors",
+ ["(l::nat) * m < n", "(l::nat) < m * n"],
+ K LessCancelNumeralFactor.proc),
+ ("natle_cancel_numeral_factors",
+ ["(l::nat) * m <= n", "(l::nat) <= m * n"],
+ K LeCancelNumeralFactor.proc),
+ ("natdiv_cancel_numeral_factors",
+ ["((l::nat) * m) div n", "(l::nat) div (m * n)"],
+ K DivCancelNumeralFactor.proc),
+ ("natdvd_cancel_numeral_factors",
+ ["((l::nat) * m) dvd n", "(l::nat) dvd (m * n)"],
+ K DvdCancelNumeralFactor.proc)];
+
+
+
+(*** Applying ExtractCommonTermFun ***)
+
+(*this version ALWAYS includes a trailing one*)
+fun long_mk_prod [] = one
+ | long_mk_prod (t :: ts) = mk_times (t, mk_prod ts);
+
+(*Find first term that matches u*)
+fun find_first_t past u [] = raise TERM("find_first_t", [])
+ | find_first_t past u (t::terms) =
+ if u aconv t then (rev past @ terms)
+ else find_first_t (t::past) u terms
+ handle TERM _ => find_first_t (t::past) u terms;
+
+(** Final simplification for the CancelFactor simprocs **)
+val simplify_one = Arith_Data.simplify_meta_eq
+ [@{thm mult_1_left}, @{thm mult_1_right}, @{thm div_1}, @{thm numeral_1_eq_Suc_0}];
+
+fun cancel_simplify_meta_eq ss cancel_th th =
+ simplify_one ss (([th, cancel_th]) MRS trans);
+
+structure CancelFactorCommon =
+ struct
+ val mk_sum = (fn T:typ => long_mk_prod)
+ val dest_sum = dest_prod
+ val mk_coeff = mk_coeff
+ val dest_coeff = dest_coeff
+ val find_first = find_first_t []
+ val trans_tac = K Arith_Data.trans_tac
+ val norm_ss = HOL_ss addsimps mult_1s @ @{thms mult_ac}
+ fun norm_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss))
+ val simplify_meta_eq = cancel_simplify_meta_eq
+ end;
+
+structure EqCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_eq
+ val dest_bal = HOLogic.dest_bin "op =" HOLogic.natT
+ val simp_conv = K(K (SOME @{thm nat_mult_eq_cancel_disj}))
+);
+
+structure LessCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less} HOLogic.natT
+ val simp_conv = K(K (SOME @{thm nat_mult_less_cancel_disj}))
+);
+
+structure LeCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} HOLogic.natT
+ val simp_conv = K(K (SOME @{thm nat_mult_le_cancel_disj}))
+);
+
+structure DivideCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binop @{const_name Divides.div}
+ val dest_bal = HOLogic.dest_bin @{const_name Divides.div} HOLogic.natT
+ val simp_conv = K(K (SOME @{thm nat_mult_div_cancel_disj}))
+);
+
+structure DvdCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name Ring_and_Field.dvd}
+ val dest_bal = HOLogic.dest_bin @{const_name Ring_and_Field.dvd} HOLogic.natT
+ val simp_conv = K(K (SOME @{thm nat_mult_dvd_cancel_disj}))
+);
+
+val cancel_factor =
+ map Arith_Data.prep_simproc
+ [("nat_eq_cancel_factor",
+ ["(l::nat) * m = n", "(l::nat) = m * n"],
+ K EqCancelFactor.proc),
+ ("nat_less_cancel_factor",
+ ["(l::nat) * m < n", "(l::nat) < m * n"],
+ K LessCancelFactor.proc),
+ ("nat_le_cancel_factor",
+ ["(l::nat) * m <= n", "(l::nat) <= m * n"],
+ K LeCancelFactor.proc),
+ ("nat_divide_cancel_factor",
+ ["((l::nat) * m) div n", "(l::nat) div (m * n)"],
+ K DivideCancelFactor.proc),
+ ("nat_dvd_cancel_factor",
+ ["((l::nat) * m) dvd n", "(l::nat) dvd (m * n)"],
+ K DvdCancelFactor.proc)];
+
+end;
+
+
+Addsimprocs Nat_Numeral_Simprocs.cancel_numerals;
+Addsimprocs [Nat_Numeral_Simprocs.combine_numerals];
+Addsimprocs Nat_Numeral_Simprocs.cancel_numeral_factors;
+Addsimprocs Nat_Numeral_Simprocs.cancel_factor;
+
+
+(*examples:
+print_depth 22;
+set timing;
+set trace_simp;
+fun test s = (Goal s; by (Simp_tac 1));
+
+(*cancel_numerals*)
+test "l +( 2) + (2) + 2 + (l + 2) + (oo + 2) = (uu::nat)";
+test "(2*length xs < 2*length xs + j)";
+test "(2*length xs < length xs * 2 + j)";
+test "2*u = (u::nat)";
+test "2*u = Suc (u)";
+test "(i + j + 12 + (k::nat)) - 15 = y";
+test "(i + j + 12 + (k::nat)) - 5 = y";
+test "Suc u - 2 = y";
+test "Suc (Suc (Suc u)) - 2 = y";
+test "(i + j + 2 + (k::nat)) - 1 = y";
+test "(i + j + 1 + (k::nat)) - 2 = y";
+
+test "(2*x + (u*v) + y) - v*3*u = (w::nat)";
+test "(2*x*u*v + 5 + (u*v)*4 + y) - v*u*4 = (w::nat)";
+test "(2*x*u*v + (u*v)*4 + y) - v*u = (w::nat)";
+test "Suc (Suc (2*x*u*v + u*4 + y)) - u = w";
+test "Suc ((u*v)*4) - v*3*u = w";
+test "Suc (Suc ((u*v)*3)) - v*3*u = w";
+
+test "(i + j + 12 + (k::nat)) = u + 15 + y";
+test "(i + j + 32 + (k::nat)) - (u + 15 + y) = zz";
+test "(i + j + 12 + (k::nat)) = u + 5 + y";
+(*Suc*)
+test "(i + j + 12 + k) = Suc (u + y)";
+test "Suc (Suc (Suc (Suc (Suc (u + y))))) <= ((i + j) + 41 + k)";
+test "(i + j + 5 + k) < Suc (Suc (Suc (Suc (Suc (u + y)))))";
+test "Suc (Suc (Suc (Suc (Suc (u + y))))) - 5 = v";
+test "(i + j + 5 + k) = Suc (Suc (Suc (Suc (Suc (Suc (Suc (u + y)))))))";
+test "2*y + 3*z + 2*u = Suc (u)";
+test "2*y + 3*z + 6*w + 2*y + 3*z + 2*u = Suc (u)";
+test "2*y + 3*z + 6*w + 2*y + 3*z + 2*u = 2*y' + 3*z' + 6*w' + 2*y' + 3*z' + u + (vv::nat)";
+test "6 + 2*y + 3*z + 4*u = Suc (vv + 2*u + z)";
+test "(2*n*m) < (3*(m*n)) + (u::nat)";
+
+test "(Suc (Suc (Suc (Suc (Suc (Suc (case length (f c) of 0 => 0 | Suc k => k)))))) <= Suc 0)";
+
+test "Suc (Suc (Suc (Suc (Suc (Suc (length l1 + length l2)))))) <= length l1";
+
+test "( (Suc (Suc (Suc (Suc (Suc (length (compT P E A ST mxr e) + length l3)))))) <= length (compT P E A ST mxr e))";
+
+test "( (Suc (Suc (Suc (Suc (Suc (length (compT P E A ST mxr e) + length (compT P E (A Un \<A> e) ST mxr c))))))) <= length (compT P E A ST mxr e))";
+
+
+(*negative numerals: FAIL*)
+test "(i + j + -23 + (k::nat)) < u + 15 + y";
+test "(i + j + 3 + (k::nat)) < u + -15 + y";
+test "(i + j + -12 + (k::nat)) - 15 = y";
+test "(i + j + 12 + (k::nat)) - -15 = y";
+test "(i + j + -12 + (k::nat)) - -15 = y";
+
+(*combine_numerals*)
+test "k + 3*k = (u::nat)";
+test "Suc (i + 3) = u";
+test "Suc (i + j + 3 + k) = u";
+test "k + j + 3*k + j = (u::nat)";
+test "Suc (j*i + i + k + 5 + 3*k + i*j*4) = (u::nat)";
+test "(2*n*m) + (3*(m*n)) = (u::nat)";
+(*negative numerals: FAIL*)
+test "Suc (i + j + -3 + k) = u";
+
+(*cancel_numeral_factors*)
+test "9*x = 12 * (y::nat)";
+test "(9*x) div (12 * (y::nat)) = z";
+test "9*x < 12 * (y::nat)";
+test "9*x <= 12 * (y::nat)";
+
+(*cancel_factor*)
+test "x*k = k*(y::nat)";
+test "k = k*(y::nat)";
+test "a*(b*c) = (b::nat)";
+test "a*(b*c) = d*(b::nat)*(x*a)";
+
+test "x*k < k*(y::nat)";
+test "k < k*(y::nat)";
+test "a*(b*c) < (b::nat)";
+test "a*(b*c) < d*(b::nat)*(x*a)";
+
+test "x*k <= k*(y::nat)";
+test "k <= k*(y::nat)";
+test "a*(b*c) <= (b::nat)";
+test "a*(b*c) <= d*(b::nat)*(x*a)";
+
+test "(x*k) div (k*(y::nat)) = (uu::nat)";
+test "(k) div (k*(y::nat)) = (uu::nat)";
+test "(a*(b*c)) div ((b::nat)) = (uu::nat)";
+test "(a*(b*c)) div (d*(b::nat)*(x*a)) = (uu::nat)";
+*)
--- a/src/HOL/Tools/nat_simprocs.ML Mon May 11 09:39:53 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,574 +0,0 @@
-(* Title: HOL/Tools/nat_simprocs.ML
- Author: Lawrence C Paulson, Cambridge University Computer Laboratory
-
-Simprocs for nat numerals.
-*)
-
-structure Nat_Numeral_Simprocs =
-struct
-
-(*Maps n to #n for n = 0, 1, 2*)
-val numeral_syms = [@{thm nat_numeral_0_eq_0} RS sym, @{thm nat_numeral_1_eq_1} RS sym, @{thm numeral_2_eq_2} RS sym];
-val numeral_sym_ss = HOL_ss addsimps numeral_syms;
-
-fun rename_numerals th =
- simplify numeral_sym_ss (Thm.transfer (the_context ()) th);
-
-(*Utilities*)
-
-fun mk_number n = HOLogic.number_of_const HOLogic.natT $ HOLogic.mk_numeral n;
-fun dest_number t = Int.max (0, snd (HOLogic.dest_number t));
-
-fun find_first_numeral past (t::terms) =
- ((dest_number t, t, rev past @ terms)
- handle TERM _ => find_first_numeral (t::past) terms)
- | find_first_numeral past [] = raise TERM("find_first_numeral", []);
-
-val zero = mk_number 0;
-val mk_plus = HOLogic.mk_binop @{const_name HOL.plus};
-
-(*Thus mk_sum[t] yields t+0; longer sums don't have a trailing zero*)
-fun mk_sum [] = zero
- | mk_sum [t,u] = mk_plus (t, u)
- | mk_sum (t :: ts) = mk_plus (t, mk_sum ts);
-
-(*this version ALWAYS includes a trailing zero*)
-fun long_mk_sum [] = HOLogic.zero
- | long_mk_sum (t :: ts) = mk_plus (t, mk_sum ts);
-
-val dest_plus = HOLogic.dest_bin @{const_name HOL.plus} HOLogic.natT;
-
-
-(** Other simproc items **)
-
-val bin_simps =
- [@{thm nat_numeral_0_eq_0} RS sym, @{thm nat_numeral_1_eq_1} RS sym,
- @{thm add_nat_number_of}, @{thm nat_number_of_add_left},
- @{thm diff_nat_number_of}, @{thm le_number_of_eq_not_less},
- @{thm mult_nat_number_of}, @{thm nat_number_of_mult_left},
- @{thm less_nat_number_of},
- @{thm Let_number_of}, @{thm nat_number_of}] @
- @{thms arith_simps} @ @{thms rel_simps} @ @{thms neg_simps};
-
-
-(*** CancelNumerals simprocs ***)
-
-val one = mk_number 1;
-val mk_times = HOLogic.mk_binop @{const_name HOL.times};
-
-fun mk_prod [] = one
- | mk_prod [t] = t
- | mk_prod (t :: ts) = if t = one then mk_prod ts
- else mk_times (t, mk_prod ts);
-
-val dest_times = HOLogic.dest_bin @{const_name HOL.times} HOLogic.natT;
-
-fun dest_prod t =
- let val (t,u) = dest_times t
- in dest_prod t @ dest_prod u end
- handle TERM _ => [t];
-
-(*DON'T do the obvious simplifications; that would create special cases*)
-fun mk_coeff (k,t) = mk_times (mk_number k, t);
-
-(*Express t as a product of (possibly) a numeral with other factors, sorted*)
-fun dest_coeff t =
- let val ts = sort TermOrd.term_ord (dest_prod t)
- val (n, _, ts') = find_first_numeral [] ts
- handle TERM _ => (1, one, ts)
- in (n, mk_prod ts') end;
-
-(*Find first coefficient-term THAT MATCHES u*)
-fun find_first_coeff past u [] = raise TERM("find_first_coeff", [])
- | find_first_coeff past u (t::terms) =
- let val (n,u') = dest_coeff t
- in if u aconv u' then (n, rev past @ terms)
- else find_first_coeff (t::past) u terms
- end
- handle TERM _ => find_first_coeff (t::past) u terms;
-
-
-(*Split up a sum into the list of its constituent terms, on the way removing any
- Sucs and counting them.*)
-fun dest_Suc_sum (Const ("Suc", _) $ t, (k,ts)) = dest_Suc_sum (t, (k+1,ts))
- | dest_Suc_sum (t, (k,ts)) =
- let val (t1,t2) = dest_plus t
- in dest_Suc_sum (t1, dest_Suc_sum (t2, (k,ts))) end
- handle TERM _ => (k, t::ts);
-
-(*Code for testing whether numerals are already used in the goal*)
-fun is_numeral (Const(@{const_name Int.number_of}, _) $ w) = true
- | is_numeral _ = false;
-
-fun prod_has_numeral t = exists is_numeral (dest_prod t);
-
-(*The Sucs found in the term are converted to a binary numeral. If relaxed is false,
- an exception is raised unless the original expression contains at least one
- numeral in a coefficient position. This prevents nat_combine_numerals from
- introducing numerals to goals.*)
-fun dest_Sucs_sum relaxed t =
- let val (k,ts) = dest_Suc_sum (t,(0,[]))
- in
- if relaxed orelse exists prod_has_numeral ts then
- if k=0 then ts
- else mk_number k :: ts
- else raise TERM("Nat_Numeral_Simprocs.dest_Sucs_sum", [t])
- end;
-
-
-(*Simplify 1*n and n*1 to n*)
-val add_0s = map rename_numerals [@{thm add_0}, @{thm add_0_right}];
-val mult_1s = map rename_numerals [@{thm nat_mult_1}, @{thm nat_mult_1_right}];
-
-(*Final simplification: cancel + and *; replace Numeral0 by 0 and Numeral1 by 1*)
-
-(*And these help the simproc return False when appropriate, which helps
- the arith prover.*)
-val contra_rules = [@{thm add_Suc}, @{thm add_Suc_right}, @{thm Zero_not_Suc},
- @{thm Suc_not_Zero}, @{thm le_0_eq}];
-
-val simplify_meta_eq =
- Arith_Data.simplify_meta_eq
- ([@{thm nat_numeral_0_eq_0}, @{thm numeral_1_eq_Suc_0}, @{thm add_0}, @{thm add_0_right},
- @{thm mult_0}, @{thm mult_0_right}, @{thm mult_1}, @{thm mult_1_right}] @ contra_rules);
-
-
-(*** Applying CancelNumeralsFun ***)
-
-structure CancelNumeralsCommon =
- struct
- val mk_sum = (fn T:typ => mk_sum)
- val dest_sum = dest_Sucs_sum true
- val mk_coeff = mk_coeff
- val dest_coeff = dest_coeff
- val find_first_coeff = find_first_coeff []
- val trans_tac = K Arith_Data.trans_tac
-
- val norm_ss1 = Int_Numeral_Simprocs.num_ss addsimps numeral_syms @ add_0s @ mult_1s @
- [@{thm Suc_eq_add_numeral_1_left}] @ @{thms add_ac}
- val norm_ss2 = Int_Numeral_Simprocs.num_ss addsimps bin_simps @ @{thms add_ac} @ @{thms mult_ac}
- fun norm_tac ss =
- ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
- THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
-
- val numeral_simp_ss = HOL_ss addsimps add_0s @ bin_simps;
- fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss));
- val simplify_meta_eq = simplify_meta_eq
- end;
-
-
-structure EqCancelNumerals = CancelNumeralsFun
- (open CancelNumeralsCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_eq
- val dest_bal = HOLogic.dest_bin "op =" HOLogic.natT
- val bal_add1 = @{thm nat_eq_add_iff1} RS trans
- val bal_add2 = @{thm nat_eq_add_iff2} RS trans
-);
-
-structure LessCancelNumerals = CancelNumeralsFun
- (open CancelNumeralsCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less} HOLogic.natT
- val bal_add1 = @{thm nat_less_add_iff1} RS trans
- val bal_add2 = @{thm nat_less_add_iff2} RS trans
-);
-
-structure LeCancelNumerals = CancelNumeralsFun
- (open CancelNumeralsCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} HOLogic.natT
- val bal_add1 = @{thm nat_le_add_iff1} RS trans
- val bal_add2 = @{thm nat_le_add_iff2} RS trans
-);
-
-structure DiffCancelNumerals = CancelNumeralsFun
- (open CancelNumeralsCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binop @{const_name HOL.minus}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.minus} HOLogic.natT
- val bal_add1 = @{thm nat_diff_add_eq1} RS trans
- val bal_add2 = @{thm nat_diff_add_eq2} RS trans
-);
-
-
-val cancel_numerals =
- map Arith_Data.prep_simproc
- [("nateq_cancel_numerals",
- ["(l::nat) + m = n", "(l::nat) = m + n",
- "(l::nat) * m = n", "(l::nat) = m * n",
- "Suc m = n", "m = Suc n"],
- K EqCancelNumerals.proc),
- ("natless_cancel_numerals",
- ["(l::nat) + m < n", "(l::nat) < m + n",
- "(l::nat) * m < n", "(l::nat) < m * n",
- "Suc m < n", "m < Suc n"],
- K LessCancelNumerals.proc),
- ("natle_cancel_numerals",
- ["(l::nat) + m <= n", "(l::nat) <= m + n",
- "(l::nat) * m <= n", "(l::nat) <= m * n",
- "Suc m <= n", "m <= Suc n"],
- K LeCancelNumerals.proc),
- ("natdiff_cancel_numerals",
- ["((l::nat) + m) - n", "(l::nat) - (m + n)",
- "(l::nat) * m - n", "(l::nat) - m * n",
- "Suc m - n", "m - Suc n"],
- K DiffCancelNumerals.proc)];
-
-
-(*** Applying CombineNumeralsFun ***)
-
-structure CombineNumeralsData =
- struct
- type coeff = int
- val iszero = (fn x => x = 0)
- val add = op +
- val mk_sum = (fn T:typ => long_mk_sum) (*to work for 2*x + 3*x *)
- val dest_sum = dest_Sucs_sum false
- val mk_coeff = mk_coeff
- val dest_coeff = dest_coeff
- val left_distrib = @{thm left_add_mult_distrib} RS trans
- val prove_conv = Arith_Data.prove_conv_nohyps
- val trans_tac = K Arith_Data.trans_tac
-
- val norm_ss1 = Int_Numeral_Simprocs.num_ss addsimps numeral_syms @ add_0s @ mult_1s @ [@{thm Suc_eq_add_numeral_1}] @ @{thms add_ac}
- val norm_ss2 = Int_Numeral_Simprocs.num_ss addsimps bin_simps @ @{thms add_ac} @ @{thms mult_ac}
- fun norm_tac ss =
- ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
- THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
-
- val numeral_simp_ss = HOL_ss addsimps add_0s @ bin_simps;
- fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
- val simplify_meta_eq = simplify_meta_eq
- end;
-
-structure CombineNumerals = CombineNumeralsFun(CombineNumeralsData);
-
-val combine_numerals =
- Arith_Data.prep_simproc ("nat_combine_numerals", ["(i::nat) + j", "Suc (i + j)"], K CombineNumerals.proc);
-
-
-(*** Applying CancelNumeralFactorFun ***)
-
-structure CancelNumeralFactorCommon =
- struct
- val mk_coeff = mk_coeff
- val dest_coeff = dest_coeff
- val trans_tac = K Arith_Data.trans_tac
-
- val norm_ss1 = Int_Numeral_Simprocs.num_ss addsimps
- numeral_syms @ add_0s @ mult_1s @ [@{thm Suc_eq_add_numeral_1_left}] @ @{thms add_ac}
- val norm_ss2 = Int_Numeral_Simprocs.num_ss addsimps bin_simps @ @{thms add_ac} @ @{thms mult_ac}
- fun norm_tac ss =
- ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
- THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
-
- val numeral_simp_ss = HOL_ss addsimps bin_simps
- fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
- val simplify_meta_eq = simplify_meta_eq
- end
-
-structure DivCancelNumeralFactor = CancelNumeralFactorFun
- (open CancelNumeralFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binop @{const_name Divides.div}
- val dest_bal = HOLogic.dest_bin @{const_name Divides.div} HOLogic.natT
- val cancel = @{thm nat_mult_div_cancel1} RS trans
- val neg_exchanges = false
-)
-
-structure DvdCancelNumeralFactor = CancelNumeralFactorFun
- (open CancelNumeralFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name Ring_and_Field.dvd}
- val dest_bal = HOLogic.dest_bin @{const_name Ring_and_Field.dvd} HOLogic.natT
- val cancel = @{thm nat_mult_dvd_cancel1} RS trans
- val neg_exchanges = false
-)
-
-structure EqCancelNumeralFactor = CancelNumeralFactorFun
- (open CancelNumeralFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_eq
- val dest_bal = HOLogic.dest_bin "op =" HOLogic.natT
- val cancel = @{thm nat_mult_eq_cancel1} RS trans
- val neg_exchanges = false
-)
-
-structure LessCancelNumeralFactor = CancelNumeralFactorFun
- (open CancelNumeralFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less} HOLogic.natT
- val cancel = @{thm nat_mult_less_cancel1} RS trans
- val neg_exchanges = true
-)
-
-structure LeCancelNumeralFactor = CancelNumeralFactorFun
- (open CancelNumeralFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} HOLogic.natT
- val cancel = @{thm nat_mult_le_cancel1} RS trans
- val neg_exchanges = true
-)
-
-val cancel_numeral_factors =
- map Arith_Data.prep_simproc
- [("nateq_cancel_numeral_factors",
- ["(l::nat) * m = n", "(l::nat) = m * n"],
- K EqCancelNumeralFactor.proc),
- ("natless_cancel_numeral_factors",
- ["(l::nat) * m < n", "(l::nat) < m * n"],
- K LessCancelNumeralFactor.proc),
- ("natle_cancel_numeral_factors",
- ["(l::nat) * m <= n", "(l::nat) <= m * n"],
- K LeCancelNumeralFactor.proc),
- ("natdiv_cancel_numeral_factors",
- ["((l::nat) * m) div n", "(l::nat) div (m * n)"],
- K DivCancelNumeralFactor.proc),
- ("natdvd_cancel_numeral_factors",
- ["((l::nat) * m) dvd n", "(l::nat) dvd (m * n)"],
- K DvdCancelNumeralFactor.proc)];
-
-
-
-(*** Applying ExtractCommonTermFun ***)
-
-(*this version ALWAYS includes a trailing one*)
-fun long_mk_prod [] = one
- | long_mk_prod (t :: ts) = mk_times (t, mk_prod ts);
-
-(*Find first term that matches u*)
-fun find_first_t past u [] = raise TERM("find_first_t", [])
- | find_first_t past u (t::terms) =
- if u aconv t then (rev past @ terms)
- else find_first_t (t::past) u terms
- handle TERM _ => find_first_t (t::past) u terms;
-
-(** Final simplification for the CancelFactor simprocs **)
-val simplify_one = Arith_Data.simplify_meta_eq
- [@{thm mult_1_left}, @{thm mult_1_right}, @{thm div_1}, @{thm numeral_1_eq_Suc_0}];
-
-fun cancel_simplify_meta_eq ss cancel_th th =
- simplify_one ss (([th, cancel_th]) MRS trans);
-
-structure CancelFactorCommon =
- struct
- val mk_sum = (fn T:typ => long_mk_prod)
- val dest_sum = dest_prod
- val mk_coeff = mk_coeff
- val dest_coeff = dest_coeff
- val find_first = find_first_t []
- val trans_tac = K Arith_Data.trans_tac
- val norm_ss = HOL_ss addsimps mult_1s @ @{thms mult_ac}
- fun norm_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss))
- val simplify_meta_eq = cancel_simplify_meta_eq
- end;
-
-structure EqCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_eq
- val dest_bal = HOLogic.dest_bin "op =" HOLogic.natT
- val simp_conv = K(K (SOME @{thm nat_mult_eq_cancel_disj}))
-);
-
-structure LessCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less} HOLogic.natT
- val simp_conv = K(K (SOME @{thm nat_mult_less_cancel_disj}))
-);
-
-structure LeCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
- val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} HOLogic.natT
- val simp_conv = K(K (SOME @{thm nat_mult_le_cancel_disj}))
-);
-
-structure DivideCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binop @{const_name Divides.div}
- val dest_bal = HOLogic.dest_bin @{const_name Divides.div} HOLogic.natT
- val simp_conv = K(K (SOME @{thm nat_mult_div_cancel_disj}))
-);
-
-structure DvdCancelFactor = ExtractCommonTermFun
- (open CancelFactorCommon
- val prove_conv = Arith_Data.prove_conv
- val mk_bal = HOLogic.mk_binrel @{const_name Ring_and_Field.dvd}
- val dest_bal = HOLogic.dest_bin @{const_name Ring_and_Field.dvd} HOLogic.natT
- val simp_conv = K(K (SOME @{thm nat_mult_dvd_cancel_disj}))
-);
-
-val cancel_factor =
- map Arith_Data.prep_simproc
- [("nat_eq_cancel_factor",
- ["(l::nat) * m = n", "(l::nat) = m * n"],
- K EqCancelFactor.proc),
- ("nat_less_cancel_factor",
- ["(l::nat) * m < n", "(l::nat) < m * n"],
- K LessCancelFactor.proc),
- ("nat_le_cancel_factor",
- ["(l::nat) * m <= n", "(l::nat) <= m * n"],
- K LeCancelFactor.proc),
- ("nat_divide_cancel_factor",
- ["((l::nat) * m) div n", "(l::nat) div (m * n)"],
- K DivideCancelFactor.proc),
- ("nat_dvd_cancel_factor",
- ["((l::nat) * m) dvd n", "(l::nat) dvd (m * n)"],
- K DvdCancelFactor.proc)];
-
-end;
-
-
-Addsimprocs Nat_Numeral_Simprocs.cancel_numerals;
-Addsimprocs [Nat_Numeral_Simprocs.combine_numerals];
-Addsimprocs Nat_Numeral_Simprocs.cancel_numeral_factors;
-Addsimprocs Nat_Numeral_Simprocs.cancel_factor;
-
-
-(*examples:
-print_depth 22;
-set timing;
-set trace_simp;
-fun test s = (Goal s; by (Simp_tac 1));
-
-(*cancel_numerals*)
-test "l +( 2) + (2) + 2 + (l + 2) + (oo + 2) = (uu::nat)";
-test "(2*length xs < 2*length xs + j)";
-test "(2*length xs < length xs * 2 + j)";
-test "2*u = (u::nat)";
-test "2*u = Suc (u)";
-test "(i + j + 12 + (k::nat)) - 15 = y";
-test "(i + j + 12 + (k::nat)) - 5 = y";
-test "Suc u - 2 = y";
-test "Suc (Suc (Suc u)) - 2 = y";
-test "(i + j + 2 + (k::nat)) - 1 = y";
-test "(i + j + 1 + (k::nat)) - 2 = y";
-
-test "(2*x + (u*v) + y) - v*3*u = (w::nat)";
-test "(2*x*u*v + 5 + (u*v)*4 + y) - v*u*4 = (w::nat)";
-test "(2*x*u*v + (u*v)*4 + y) - v*u = (w::nat)";
-test "Suc (Suc (2*x*u*v + u*4 + y)) - u = w";
-test "Suc ((u*v)*4) - v*3*u = w";
-test "Suc (Suc ((u*v)*3)) - v*3*u = w";
-
-test "(i + j + 12 + (k::nat)) = u + 15 + y";
-test "(i + j + 32 + (k::nat)) - (u + 15 + y) = zz";
-test "(i + j + 12 + (k::nat)) = u + 5 + y";
-(*Suc*)
-test "(i + j + 12 + k) = Suc (u + y)";
-test "Suc (Suc (Suc (Suc (Suc (u + y))))) <= ((i + j) + 41 + k)";
-test "(i + j + 5 + k) < Suc (Suc (Suc (Suc (Suc (u + y)))))";
-test "Suc (Suc (Suc (Suc (Suc (u + y))))) - 5 = v";
-test "(i + j + 5 + k) = Suc (Suc (Suc (Suc (Suc (Suc (Suc (u + y)))))))";
-test "2*y + 3*z + 2*u = Suc (u)";
-test "2*y + 3*z + 6*w + 2*y + 3*z + 2*u = Suc (u)";
-test "2*y + 3*z + 6*w + 2*y + 3*z + 2*u = 2*y' + 3*z' + 6*w' + 2*y' + 3*z' + u + (vv::nat)";
-test "6 + 2*y + 3*z + 4*u = Suc (vv + 2*u + z)";
-test "(2*n*m) < (3*(m*n)) + (u::nat)";
-
-test "(Suc (Suc (Suc (Suc (Suc (Suc (case length (f c) of 0 => 0 | Suc k => k)))))) <= Suc 0)";
-
-test "Suc (Suc (Suc (Suc (Suc (Suc (length l1 + length l2)))))) <= length l1";
-
-test "( (Suc (Suc (Suc (Suc (Suc (length (compT P E A ST mxr e) + length l3)))))) <= length (compT P E A ST mxr e))";
-
-test "( (Suc (Suc (Suc (Suc (Suc (length (compT P E A ST mxr e) + length (compT P E (A Un \<A> e) ST mxr c))))))) <= length (compT P E A ST mxr e))";
-
-
-(*negative numerals: FAIL*)
-test "(i + j + -23 + (k::nat)) < u + 15 + y";
-test "(i + j + 3 + (k::nat)) < u + -15 + y";
-test "(i + j + -12 + (k::nat)) - 15 = y";
-test "(i + j + 12 + (k::nat)) - -15 = y";
-test "(i + j + -12 + (k::nat)) - -15 = y";
-
-(*combine_numerals*)
-test "k + 3*k = (u::nat)";
-test "Suc (i + 3) = u";
-test "Suc (i + j + 3 + k) = u";
-test "k + j + 3*k + j = (u::nat)";
-test "Suc (j*i + i + k + 5 + 3*k + i*j*4) = (u::nat)";
-test "(2*n*m) + (3*(m*n)) = (u::nat)";
-(*negative numerals: FAIL*)
-test "Suc (i + j + -3 + k) = u";
-
-(*cancel_numeral_factors*)
-test "9*x = 12 * (y::nat)";
-test "(9*x) div (12 * (y::nat)) = z";
-test "9*x < 12 * (y::nat)";
-test "9*x <= 12 * (y::nat)";
-
-(*cancel_factor*)
-test "x*k = k*(y::nat)";
-test "k = k*(y::nat)";
-test "a*(b*c) = (b::nat)";
-test "a*(b*c) = d*(b::nat)*(x*a)";
-
-test "x*k < k*(y::nat)";
-test "k < k*(y::nat)";
-test "a*(b*c) < (b::nat)";
-test "a*(b*c) < d*(b::nat)*(x*a)";
-
-test "x*k <= k*(y::nat)";
-test "k <= k*(y::nat)";
-test "a*(b*c) <= (b::nat)";
-test "a*(b*c) <= d*(b::nat)*(x*a)";
-
-test "(x*k) div (k*(y::nat)) = (uu::nat)";
-test "(k) div (k*(y::nat)) = (uu::nat)";
-test "(a*(b*c)) div ((b::nat)) = (uu::nat)";
-test "(a*(b*c)) div (d*(b::nat)*(x*a)) = (uu::nat)";
-*)
-
-
-(*** Prepare linear arithmetic for nat numerals ***)
-
-local
-
-(* reduce contradictory <= to False *)
-val add_rules = @{thms ring_distribs} @
- [@{thm Let_number_of}, @{thm Let_0}, @{thm Let_1}, @{thm nat_0}, @{thm nat_1},
- @{thm add_nat_number_of}, @{thm diff_nat_number_of}, @{thm mult_nat_number_of},
- @{thm eq_nat_number_of}, @{thm less_nat_number_of}, @{thm le_number_of_eq_not_less},
- @{thm le_Suc_number_of}, @{thm le_number_of_Suc},
- @{thm less_Suc_number_of}, @{thm less_number_of_Suc},
- @{thm Suc_eq_number_of}, @{thm eq_number_of_Suc},
- @{thm mult_Suc}, @{thm mult_Suc_right},
- @{thm add_Suc}, @{thm add_Suc_right},
- @{thm eq_number_of_0}, @{thm eq_0_number_of}, @{thm less_0_number_of},
- @{thm of_int_number_of_eq}, @{thm of_nat_number_of_eq}, @{thm nat_number_of}, @{thm if_True}, @{thm if_False}];
-
-(* Products are multiplied out during proof (re)construction via
-ring_distribs. Ideally they should remain atomic. But that is
-currently not possible because 1 is replaced by Suc 0, and then some
-simprocs start to mess around with products like (n+1)*m. The rule
-1 == Suc 0 is necessary for early parts of HOL where numerals and
-simprocs are not yet available. But then it is difficult to remove
-that rule later on, because it may find its way back in when theories
-(and thus lin-arith simpsets) are merged. Otherwise one could turn the
-rule around (Suc n = n+1) and see if that helps products being left
-alone. *)
-
-val simprocs = Nat_Numeral_Simprocs.combine_numerals
- :: Nat_Numeral_Simprocs.cancel_numerals;
-
-in
-
-val nat_simprocs_setup =
- Lin_Arith.map_data (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset} =>
- {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms,
- inj_thms = inj_thms, lessD = lessD, neqE = neqE,
- simpset = simpset addsimps add_rules
- addsimprocs simprocs});
-
-end;
--- a/src/HOL/Tools/numeral.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/numeral.ML Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title: HOL/Tools/numeral.ML
- ID: $Id$
Author: Makarius
Logical operations on numerals (see also HOL/hologic.ML).
@@ -59,13 +58,8 @@
fun add_code number_of negative unbounded target thy =
let
- val pr_numeral = (Code_Printer.literal_numeral o Code_Target.the_literals thy) target;
- fun dest_numeral naming thm =
+ fun dest_numeral pls' min' bit0' bit1' thm =
let
- val SOME pls' = Code_Thingol.lookup_const naming @{const_name Int.Pls};
- val SOME min' = Code_Thingol.lookup_const naming @{const_name Int.Min};
- val SOME bit0' = Code_Thingol.lookup_const naming @{const_name Int.Bit0};
- val SOME bit1' = Code_Thingol.lookup_const naming @{const_name Int.Bit1};
fun dest_bit (IConst (c, _)) = if c = bit0' then 0
else if c = bit1' then 1
else Code_Printer.nerror thm "Illegal numeral expression: illegal bit"
@@ -79,11 +73,12 @@
in case n of SOME n => SOME (2 * n + b) | NONE => NONE end
| dest_num _ = Code_Printer.nerror thm "Illegal numeral expression: illegal term";
in dest_num end;
- fun pretty _ naming thm _ _ [(t, _)] =
- (Code_Printer.str o pr_numeral unbounded o the_default 0 o dest_numeral naming thm) t;
+ fun pretty literals [pls', min', bit0', bit1'] _ thm _ _ [(t, _)] =
+ (Code_Printer.str o Code_Printer.literal_numeral literals unbounded
+ o the_default 0 o dest_numeral pls' min' bit0' bit1' thm) t;
in
- thy
- |> Code_Target.add_syntax_const target number_of (SOME (1, pretty))
+ thy |> Code_Target.add_syntax_const target number_of
+ (SOME (1, ([@{const_name Int.Pls}, @{const_name Int.Min}, @{const_name Int.Bit0}, @{const_name Int.Bit1}], pretty)))
end;
end; (*local*)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Tools/numeral_simprocs.ML Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,786 @@
+(* Author: Lawrence C Paulson, Cambridge University Computer Laboratory
+ Copyright 2000 University of Cambridge
+
+Simprocs for the integer numerals.
+*)
+
+(*To quote from Provers/Arith/cancel_numeral_factor.ML:
+
+Cancels common coefficients in balanced expressions:
+
+ u*#m ~~ u'*#m' == #n*u ~~ #n'*u'
+
+where ~~ is an appropriate balancing operation (e.g. =, <=, <, div, /)
+and d = gcd(m,m') and n=m/d and n'=m'/d.
+*)
+
+signature NUMERAL_SIMPROCS =
+sig
+ val mk_sum: typ -> term list -> term
+ val dest_sum: term -> term list
+
+ val assoc_fold_simproc: simproc
+ val combine_numerals: simproc
+ val cancel_numerals: simproc list
+ val cancel_factors: simproc list
+ val cancel_numeral_factors: simproc list
+ val field_combine_numerals: simproc
+ val field_cancel_numeral_factors: simproc list
+ val num_ss: simpset
+end;
+
+structure Numeral_Simprocs : NUMERAL_SIMPROCS =
+struct
+
+fun mk_number T n = HOLogic.number_of_const T $ HOLogic.mk_numeral n;
+
+fun find_first_numeral past (t::terms) =
+ ((snd (HOLogic.dest_number t), rev past @ terms)
+ handle TERM _ => find_first_numeral (t::past) terms)
+ | find_first_numeral past [] = raise TERM("find_first_numeral", []);
+
+val mk_plus = HOLogic.mk_binop @{const_name HOL.plus};
+
+fun mk_minus t =
+ let val T = Term.fastype_of t
+ in Const (@{const_name HOL.uminus}, T --> T) $ t end;
+
+(*Thus mk_sum[t] yields t+0; longer sums don't have a trailing zero*)
+fun mk_sum T [] = mk_number T 0
+ | mk_sum T [t,u] = mk_plus (t, u)
+ | mk_sum T (t :: ts) = mk_plus (t, mk_sum T ts);
+
+(*this version ALWAYS includes a trailing zero*)
+fun long_mk_sum T [] = mk_number T 0
+ | long_mk_sum T (t :: ts) = mk_plus (t, mk_sum T ts);
+
+val dest_plus = HOLogic.dest_bin @{const_name HOL.plus} Term.dummyT;
+
+(*decompose additions AND subtractions as a sum*)
+fun dest_summing (pos, Const (@{const_name HOL.plus}, _) $ t $ u, ts) =
+ dest_summing (pos, t, dest_summing (pos, u, ts))
+ | dest_summing (pos, Const (@{const_name HOL.minus}, _) $ t $ u, ts) =
+ dest_summing (pos, t, dest_summing (not pos, u, ts))
+ | dest_summing (pos, t, ts) =
+ if pos then t::ts else mk_minus t :: ts;
+
+fun dest_sum t = dest_summing (true, t, []);
+
+val mk_diff = HOLogic.mk_binop @{const_name HOL.minus};
+val dest_diff = HOLogic.dest_bin @{const_name HOL.minus} Term.dummyT;
+
+val mk_times = HOLogic.mk_binop @{const_name HOL.times};
+
+fun one_of T = Const(@{const_name HOL.one},T);
+
+(* build product with trailing 1 rather than Numeral 1 in order to avoid the
+ unnecessary restriction to type class number_ring
+ which is not required for cancellation of common factors in divisions.
+*)
+fun mk_prod T =
+ let val one = one_of T
+ fun mk [] = one
+ | mk [t] = t
+ | mk (t :: ts) = if t = one then mk ts else mk_times (t, mk ts)
+ in mk end;
+
+(*This version ALWAYS includes a trailing one*)
+fun long_mk_prod T [] = one_of T
+ | long_mk_prod T (t :: ts) = mk_times (t, mk_prod T ts);
+
+val dest_times = HOLogic.dest_bin @{const_name HOL.times} Term.dummyT;
+
+fun dest_prod t =
+ let val (t,u) = dest_times t
+ in dest_prod t @ dest_prod u end
+ handle TERM _ => [t];
+
+(*DON'T do the obvious simplifications; that would create special cases*)
+fun mk_coeff (k, t) = mk_times (mk_number (Term.fastype_of t) k, t);
+
+(*Express t as a product of (possibly) a numeral with other sorted terms*)
+fun dest_coeff sign (Const (@{const_name HOL.uminus}, _) $ t) = dest_coeff (~sign) t
+ | dest_coeff sign t =
+ let val ts = sort TermOrd.term_ord (dest_prod t)
+ val (n, ts') = find_first_numeral [] ts
+ handle TERM _ => (1, ts)
+ in (sign*n, mk_prod (Term.fastype_of t) ts') end;
+
+(*Find first coefficient-term THAT MATCHES u*)
+fun find_first_coeff past u [] = raise TERM("find_first_coeff", [])
+ | find_first_coeff past u (t::terms) =
+ let val (n,u') = dest_coeff 1 t
+ in if u aconv u' then (n, rev past @ terms)
+ else find_first_coeff (t::past) u terms
+ end
+ handle TERM _ => find_first_coeff (t::past) u terms;
+
+(*Fractions as pairs of ints. Can't use Rat.rat because the representation
+ needs to preserve negative values in the denominator.*)
+fun mk_frac (p, q) = if q = 0 then raise Div else (p, q);
+
+(*Don't reduce fractions; sums must be proved by rule add_frac_eq.
+ Fractions are reduced later by the cancel_numeral_factor simproc.*)
+fun add_frac ((p1, q1), (p2, q2)) = (p1 * q2 + p2 * q1, q1 * q2);
+
+val mk_divide = HOLogic.mk_binop @{const_name HOL.divide};
+
+(*Build term (p / q) * t*)
+fun mk_fcoeff ((p, q), t) =
+ let val T = Term.fastype_of t
+ in mk_times (mk_divide (mk_number T p, mk_number T q), t) end;
+
+(*Express t as a product of a fraction with other sorted terms*)
+fun dest_fcoeff sign (Const (@{const_name HOL.uminus}, _) $ t) = dest_fcoeff (~sign) t
+ | dest_fcoeff sign (Const (@{const_name HOL.divide}, _) $ t $ u) =
+ let val (p, t') = dest_coeff sign t
+ val (q, u') = dest_coeff 1 u
+ in (mk_frac (p, q), mk_divide (t', u')) end
+ | dest_fcoeff sign t =
+ let val (p, t') = dest_coeff sign t
+ val T = Term.fastype_of t
+ in (mk_frac (p, 1), mk_divide (t', one_of T)) end;
+
+
+(** New term ordering so that AC-rewriting brings numerals to the front **)
+
+(*Order integers by absolute value and then by sign. The standard integer
+ ordering is not well-founded.*)
+fun num_ord (i,j) =
+ (case int_ord (abs i, abs j) of
+ EQUAL => int_ord (Int.sign i, Int.sign j)
+ | ord => ord);
+
+(*This resembles TermOrd.term_ord, but it puts binary numerals before other
+ non-atomic terms.*)
+local open Term
+in
+fun numterm_ord (Abs (_, T, t), Abs(_, U, u)) =
+ (case numterm_ord (t, u) of EQUAL => TermOrd.typ_ord (T, U) | ord => ord)
+ | numterm_ord
+ (Const(@{const_name Int.number_of}, _) $ v, Const(@{const_name Int.number_of}, _) $ w) =
+ num_ord (HOLogic.dest_numeral v, HOLogic.dest_numeral w)
+ | numterm_ord (Const(@{const_name Int.number_of}, _) $ _, _) = LESS
+ | numterm_ord (_, Const(@{const_name Int.number_of}, _) $ _) = GREATER
+ | numterm_ord (t, u) =
+ (case int_ord (size_of_term t, size_of_term u) of
+ EQUAL =>
+ let val (f, ts) = strip_comb t and (g, us) = strip_comb u in
+ (case TermOrd.hd_ord (f, g) of EQUAL => numterms_ord (ts, us) | ord => ord)
+ end
+ | ord => ord)
+and numterms_ord (ts, us) = list_ord numterm_ord (ts, us)
+end;
+
+fun numtermless tu = (numterm_ord tu = LESS);
+
+val num_ss = HOL_ss settermless numtermless;
+
+(*Maps 0 to Numeral0 and 1 to Numeral1 so that arithmetic isn't complicated by the abstract 0 and 1.*)
+val numeral_syms = [@{thm numeral_0_eq_0} RS sym, @{thm numeral_1_eq_1} RS sym];
+
+(*Simplify Numeral0+n, n+Numeral0, Numeral1*n, n*Numeral1, 1*x, x*1, x/1 *)
+val add_0s = @{thms add_0s};
+val mult_1s = @{thms mult_1s mult_1_left mult_1_right divide_1};
+
+(*Simplify inverse Numeral1, a/Numeral1*)
+val inverse_1s = [@{thm inverse_numeral_1}];
+val divide_1s = [@{thm divide_numeral_1}];
+
+(*To perform binary arithmetic. The "left" rewriting handles patterns
+ created by the Numeral_Simprocs, such as 3 * (5 * x). *)
+val simps = [@{thm numeral_0_eq_0} RS sym, @{thm numeral_1_eq_1} RS sym,
+ @{thm add_number_of_left}, @{thm mult_number_of_left}] @
+ @{thms arith_simps} @ @{thms rel_simps};
+
+(*Binary arithmetic BUT NOT ADDITION since it may collapse adjacent terms
+ during re-arrangement*)
+val non_add_simps =
+ subtract Thm.eq_thm [@{thm add_number_of_left}, @{thm number_of_add} RS sym] simps;
+
+(*To evaluate binary negations of coefficients*)
+val minus_simps = [@{thm numeral_m1_eq_minus_1} RS sym, @{thm number_of_minus} RS sym] @
+ @{thms minus_bin_simps} @ @{thms pred_bin_simps};
+
+(*To let us treat subtraction as addition*)
+val diff_simps = [@{thm diff_minus}, @{thm minus_add_distrib}, @{thm minus_minus}];
+
+(*To let us treat division as multiplication*)
+val divide_simps = [@{thm divide_inverse}, @{thm inverse_mult_distrib}, @{thm inverse_inverse_eq}];
+
+(*push the unary minus down: - x * y = x * - y *)
+val minus_mult_eq_1_to_2 =
+ [@{thm mult_minus_left}, @{thm minus_mult_right}] MRS trans |> standard;
+
+(*to extract again any uncancelled minuses*)
+val minus_from_mult_simps =
+ [@{thm minus_minus}, @{thm mult_minus_left}, @{thm mult_minus_right}];
+
+(*combine unary minus with numeric literals, however nested within a product*)
+val mult_minus_simps =
+ [@{thm mult_assoc}, @{thm minus_mult_left}, minus_mult_eq_1_to_2];
+
+val norm_ss1 = num_ss addsimps numeral_syms @ add_0s @ mult_1s @
+ diff_simps @ minus_simps @ @{thms add_ac}
+val norm_ss2 = num_ss addsimps non_add_simps @ mult_minus_simps
+val norm_ss3 = num_ss addsimps minus_from_mult_simps @ @{thms add_ac} @ @{thms mult_ac}
+
+structure CancelNumeralsCommon =
+ struct
+ val mk_sum = mk_sum
+ val dest_sum = dest_sum
+ val mk_coeff = mk_coeff
+ val dest_coeff = dest_coeff 1
+ val find_first_coeff = find_first_coeff []
+ val trans_tac = K Arith_Data.trans_tac
+
+ fun norm_tac ss =
+ ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
+ THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
+ THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
+
+ val numeral_simp_ss = HOL_ss addsimps add_0s @ simps
+ fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
+ val simplify_meta_eq = Arith_Data.simplify_meta_eq (add_0s @ mult_1s)
+ end;
+
+
+structure EqCancelNumerals = CancelNumeralsFun
+ (open CancelNumeralsCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_eq
+ val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
+ val bal_add1 = @{thm eq_add_iff1} RS trans
+ val bal_add2 = @{thm eq_add_iff2} RS trans
+);
+
+structure LessCancelNumerals = CancelNumeralsFun
+ (open CancelNumeralsCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less} Term.dummyT
+ val bal_add1 = @{thm less_add_iff1} RS trans
+ val bal_add2 = @{thm less_add_iff2} RS trans
+);
+
+structure LeCancelNumerals = CancelNumeralsFun
+ (open CancelNumeralsCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} Term.dummyT
+ val bal_add1 = @{thm le_add_iff1} RS trans
+ val bal_add2 = @{thm le_add_iff2} RS trans
+);
+
+val cancel_numerals =
+ map Arith_Data.prep_simproc
+ [("inteq_cancel_numerals",
+ ["(l::'a::number_ring) + m = n",
+ "(l::'a::number_ring) = m + n",
+ "(l::'a::number_ring) - m = n",
+ "(l::'a::number_ring) = m - n",
+ "(l::'a::number_ring) * m = n",
+ "(l::'a::number_ring) = m * n"],
+ K EqCancelNumerals.proc),
+ ("intless_cancel_numerals",
+ ["(l::'a::{ordered_idom,number_ring}) + m < n",
+ "(l::'a::{ordered_idom,number_ring}) < m + n",
+ "(l::'a::{ordered_idom,number_ring}) - m < n",
+ "(l::'a::{ordered_idom,number_ring}) < m - n",
+ "(l::'a::{ordered_idom,number_ring}) * m < n",
+ "(l::'a::{ordered_idom,number_ring}) < m * n"],
+ K LessCancelNumerals.proc),
+ ("intle_cancel_numerals",
+ ["(l::'a::{ordered_idom,number_ring}) + m <= n",
+ "(l::'a::{ordered_idom,number_ring}) <= m + n",
+ "(l::'a::{ordered_idom,number_ring}) - m <= n",
+ "(l::'a::{ordered_idom,number_ring}) <= m - n",
+ "(l::'a::{ordered_idom,number_ring}) * m <= n",
+ "(l::'a::{ordered_idom,number_ring}) <= m * n"],
+ K LeCancelNumerals.proc)];
+
+structure CombineNumeralsData =
+ struct
+ type coeff = int
+ val iszero = (fn x => x = 0)
+ val add = op +
+ val mk_sum = long_mk_sum (*to work for e.g. 2*x + 3*x *)
+ val dest_sum = dest_sum
+ val mk_coeff = mk_coeff
+ val dest_coeff = dest_coeff 1
+ val left_distrib = @{thm combine_common_factor} RS trans
+ val prove_conv = Arith_Data.prove_conv_nohyps
+ val trans_tac = K Arith_Data.trans_tac
+
+ fun norm_tac ss =
+ ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
+ THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
+ THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
+
+ val numeral_simp_ss = HOL_ss addsimps add_0s @ simps
+ fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
+ val simplify_meta_eq = Arith_Data.simplify_meta_eq (add_0s @ mult_1s)
+ end;
+
+structure CombineNumerals = CombineNumeralsFun(CombineNumeralsData);
+
+(*Version for fields, where coefficients can be fractions*)
+structure FieldCombineNumeralsData =
+ struct
+ type coeff = int * int
+ val iszero = (fn (p, q) => p = 0)
+ val add = add_frac
+ val mk_sum = long_mk_sum
+ val dest_sum = dest_sum
+ val mk_coeff = mk_fcoeff
+ val dest_coeff = dest_fcoeff 1
+ val left_distrib = @{thm combine_common_factor} RS trans
+ val prove_conv = Arith_Data.prove_conv_nohyps
+ val trans_tac = K Arith_Data.trans_tac
+
+ val norm_ss1a = norm_ss1 addsimps inverse_1s @ divide_simps
+ fun norm_tac ss =
+ ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1a))
+ THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
+ THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
+
+ val numeral_simp_ss = HOL_ss addsimps add_0s @ simps @ [@{thm add_frac_eq}]
+ fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
+ val simplify_meta_eq = Arith_Data.simplify_meta_eq (add_0s @ mult_1s @ divide_1s)
+ end;
+
+structure FieldCombineNumerals = CombineNumeralsFun(FieldCombineNumeralsData);
+
+val combine_numerals =
+ Arith_Data.prep_simproc
+ ("int_combine_numerals",
+ ["(i::'a::number_ring) + j", "(i::'a::number_ring) - j"],
+ K CombineNumerals.proc);
+
+val field_combine_numerals =
+ Arith_Data.prep_simproc
+ ("field_combine_numerals",
+ ["(i::'a::{number_ring,field,division_by_zero}) + j",
+ "(i::'a::{number_ring,field,division_by_zero}) - j"],
+ K FieldCombineNumerals.proc);
+
+(** Constant folding for multiplication in semirings **)
+
+(*We do not need folding for addition: combine_numerals does the same thing*)
+
+structure Semiring_Times_Assoc_Data : ASSOC_FOLD_DATA =
+struct
+ val assoc_ss = HOL_ss addsimps @{thms mult_ac}
+ val eq_reflection = eq_reflection
+ fun is_numeral (Const(@{const_name Int.number_of}, _) $ _) = true
+ | is_numeral _ = false;
+end;
+
+structure Semiring_Times_Assoc = Assoc_Fold (Semiring_Times_Assoc_Data);
+
+val assoc_fold_simproc =
+ Arith_Data.prep_simproc
+ ("semiring_assoc_fold", ["(a::'a::comm_semiring_1_cancel) * b"],
+ K Semiring_Times_Assoc.proc);
+
+structure CancelNumeralFactorCommon =
+ struct
+ val mk_coeff = mk_coeff
+ val dest_coeff = dest_coeff 1
+ val trans_tac = K Arith_Data.trans_tac
+
+ val norm_ss1 = HOL_ss addsimps minus_from_mult_simps @ mult_1s
+ val norm_ss2 = HOL_ss addsimps simps @ mult_minus_simps
+ val norm_ss3 = HOL_ss addsimps @{thms mult_ac}
+ fun norm_tac ss =
+ ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
+ THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
+ THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
+
+ val numeral_simp_ss = HOL_ss addsimps
+ [@{thm eq_number_of_eq}, @{thm less_number_of}, @{thm le_number_of}] @ simps
+ fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
+ val simplify_meta_eq = Arith_Data.simplify_meta_eq
+ [@{thm add_0}, @{thm add_0_right}, @{thm mult_zero_left},
+ @{thm mult_zero_right}, @{thm mult_Bit1}, @{thm mult_1_right}];
+ end
+
+(*Version for semiring_div*)
+structure DivCancelNumeralFactor = CancelNumeralFactorFun
+ (open CancelNumeralFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binop @{const_name Divides.div}
+ val dest_bal = HOLogic.dest_bin @{const_name Divides.div} Term.dummyT
+ val cancel = @{thm div_mult_mult1} RS trans
+ val neg_exchanges = false
+)
+
+(*Version for fields*)
+structure DivideCancelNumeralFactor = CancelNumeralFactorFun
+ (open CancelNumeralFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binop @{const_name HOL.divide}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.divide} Term.dummyT
+ val cancel = @{thm mult_divide_mult_cancel_left} RS trans
+ val neg_exchanges = false
+)
+
+structure EqCancelNumeralFactor = CancelNumeralFactorFun
+ (open CancelNumeralFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_eq
+ val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
+ val cancel = @{thm mult_cancel_left} RS trans
+ val neg_exchanges = false
+)
+
+structure LessCancelNumeralFactor = CancelNumeralFactorFun
+ (open CancelNumeralFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less} Term.dummyT
+ val cancel = @{thm mult_less_cancel_left} RS trans
+ val neg_exchanges = true
+)
+
+structure LeCancelNumeralFactor = CancelNumeralFactorFun
+ (open CancelNumeralFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} Term.dummyT
+ val cancel = @{thm mult_le_cancel_left} RS trans
+ val neg_exchanges = true
+)
+
+val cancel_numeral_factors =
+ map Arith_Data.prep_simproc
+ [("ring_eq_cancel_numeral_factor",
+ ["(l::'a::{idom,number_ring}) * m = n",
+ "(l::'a::{idom,number_ring}) = m * n"],
+ K EqCancelNumeralFactor.proc),
+ ("ring_less_cancel_numeral_factor",
+ ["(l::'a::{ordered_idom,number_ring}) * m < n",
+ "(l::'a::{ordered_idom,number_ring}) < m * n"],
+ K LessCancelNumeralFactor.proc),
+ ("ring_le_cancel_numeral_factor",
+ ["(l::'a::{ordered_idom,number_ring}) * m <= n",
+ "(l::'a::{ordered_idom,number_ring}) <= m * n"],
+ K LeCancelNumeralFactor.proc),
+ ("int_div_cancel_numeral_factors",
+ ["((l::'a::{semiring_div,number_ring}) * m) div n",
+ "(l::'a::{semiring_div,number_ring}) div (m * n)"],
+ K DivCancelNumeralFactor.proc),
+ ("divide_cancel_numeral_factor",
+ ["((l::'a::{division_by_zero,field,number_ring}) * m) / n",
+ "(l::'a::{division_by_zero,field,number_ring}) / (m * n)",
+ "((number_of v)::'a::{division_by_zero,field,number_ring}) / (number_of w)"],
+ K DivideCancelNumeralFactor.proc)];
+
+val field_cancel_numeral_factors =
+ map Arith_Data.prep_simproc
+ [("field_eq_cancel_numeral_factor",
+ ["(l::'a::{field,number_ring}) * m = n",
+ "(l::'a::{field,number_ring}) = m * n"],
+ K EqCancelNumeralFactor.proc),
+ ("field_cancel_numeral_factor",
+ ["((l::'a::{division_by_zero,field,number_ring}) * m) / n",
+ "(l::'a::{division_by_zero,field,number_ring}) / (m * n)",
+ "((number_of v)::'a::{division_by_zero,field,number_ring}) / (number_of w)"],
+ K DivideCancelNumeralFactor.proc)]
+
+
+(** Declarations for ExtractCommonTerm **)
+
+(*Find first term that matches u*)
+fun find_first_t past u [] = raise TERM ("find_first_t", [])
+ | find_first_t past u (t::terms) =
+ if u aconv t then (rev past @ terms)
+ else find_first_t (t::past) u terms
+ handle TERM _ => find_first_t (t::past) u terms;
+
+(** Final simplification for the CancelFactor simprocs **)
+val simplify_one = Arith_Data.simplify_meta_eq
+ [@{thm mult_1_left}, @{thm mult_1_right}, @{thm div_by_1}, @{thm numeral_1_eq_1}];
+
+fun cancel_simplify_meta_eq ss cancel_th th =
+ simplify_one ss (([th, cancel_th]) MRS trans);
+
+local
+ val Tp_Eq = Thm.reflexive (Thm.cterm_of @{theory HOL} HOLogic.Trueprop)
+ fun Eq_True_elim Eq =
+ Thm.equal_elim (Thm.combination Tp_Eq (Thm.symmetric Eq)) @{thm TrueI}
+in
+fun sign_conv pos_th neg_th ss t =
+ let val T = fastype_of t;
+ val zero = Const(@{const_name HOL.zero}, T);
+ val less = Const(@{const_name HOL.less}, [T,T] ---> HOLogic.boolT);
+ val pos = less $ zero $ t and neg = less $ t $ zero
+ fun prove p =
+ Option.map Eq_True_elim (Lin_Arith.lin_arith_simproc ss p)
+ handle THM _ => NONE
+ in case prove pos of
+ SOME th => SOME(th RS pos_th)
+ | NONE => (case prove neg of
+ SOME th => SOME(th RS neg_th)
+ | NONE => NONE)
+ end;
+end
+
+structure CancelFactorCommon =
+ struct
+ val mk_sum = long_mk_prod
+ val dest_sum = dest_prod
+ val mk_coeff = mk_coeff
+ val dest_coeff = dest_coeff
+ val find_first = find_first_t []
+ val trans_tac = K Arith_Data.trans_tac
+ val norm_ss = HOL_ss addsimps mult_1s @ @{thms mult_ac}
+ fun norm_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss))
+ val simplify_meta_eq = cancel_simplify_meta_eq
+ end;
+
+(*mult_cancel_left requires a ring with no zero divisors.*)
+structure EqCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_eq
+ val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
+ val simp_conv = K (K (SOME @{thm mult_cancel_left}))
+);
+
+(*for ordered rings*)
+structure LeCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less_eq}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less_eq} Term.dummyT
+ val simp_conv = sign_conv
+ @{thm mult_le_cancel_left_pos} @{thm mult_le_cancel_left_neg}
+);
+
+(*for ordered rings*)
+structure LessCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name HOL.less}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.less} Term.dummyT
+ val simp_conv = sign_conv
+ @{thm mult_less_cancel_left_pos} @{thm mult_less_cancel_left_neg}
+);
+
+(*for semirings with division*)
+structure DivCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binop @{const_name Divides.div}
+ val dest_bal = HOLogic.dest_bin @{const_name Divides.div} Term.dummyT
+ val simp_conv = K (K (SOME @{thm div_mult_mult1_if}))
+);
+
+structure ModCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binop @{const_name Divides.mod}
+ val dest_bal = HOLogic.dest_bin @{const_name Divides.mod} Term.dummyT
+ val simp_conv = K (K (SOME @{thm mod_mult_mult1}))
+);
+
+(*for idoms*)
+structure DvdCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binrel @{const_name Ring_and_Field.dvd}
+ val dest_bal = HOLogic.dest_bin @{const_name Ring_and_Field.dvd} Term.dummyT
+ val simp_conv = K (K (SOME @{thm dvd_mult_cancel_left}))
+);
+
+(*Version for all fields, including unordered ones (type complex).*)
+structure DivideCancelFactor = ExtractCommonTermFun
+ (open CancelFactorCommon
+ val prove_conv = Arith_Data.prove_conv
+ val mk_bal = HOLogic.mk_binop @{const_name HOL.divide}
+ val dest_bal = HOLogic.dest_bin @{const_name HOL.divide} Term.dummyT
+ val simp_conv = K (K (SOME @{thm mult_divide_mult_cancel_left_if}))
+);
+
+val cancel_factors =
+ map Arith_Data.prep_simproc
+ [("ring_eq_cancel_factor",
+ ["(l::'a::idom) * m = n",
+ "(l::'a::idom) = m * n"],
+ K EqCancelFactor.proc),
+ ("ordered_ring_le_cancel_factor",
+ ["(l::'a::ordered_ring) * m <= n",
+ "(l::'a::ordered_ring) <= m * n"],
+ K LeCancelFactor.proc),
+ ("ordered_ring_less_cancel_factor",
+ ["(l::'a::ordered_ring) * m < n",
+ "(l::'a::ordered_ring) < m * n"],
+ K LessCancelFactor.proc),
+ ("int_div_cancel_factor",
+ ["((l::'a::semiring_div) * m) div n", "(l::'a::semiring_div) div (m * n)"],
+ K DivCancelFactor.proc),
+ ("int_mod_cancel_factor",
+ ["((l::'a::semiring_div) * m) mod n", "(l::'a::semiring_div) mod (m * n)"],
+ K ModCancelFactor.proc),
+ ("dvd_cancel_factor",
+ ["((l::'a::idom) * m) dvd n", "(l::'a::idom) dvd (m * n)"],
+ K DvdCancelFactor.proc),
+ ("divide_cancel_factor",
+ ["((l::'a::{division_by_zero,field}) * m) / n",
+ "(l::'a::{division_by_zero,field}) / (m * n)"],
+ K DivideCancelFactor.proc)];
+
+end;
+
+Addsimprocs Numeral_Simprocs.cancel_numerals;
+Addsimprocs [Numeral_Simprocs.combine_numerals];
+Addsimprocs [Numeral_Simprocs.field_combine_numerals];
+Addsimprocs [Numeral_Simprocs.assoc_fold_simproc];
+
+(*examples:
+print_depth 22;
+set timing;
+set trace_simp;
+fun test s = (Goal s, by (Simp_tac 1));
+
+test "l + 2 + 2 + 2 + (l + 2) + (oo + 2) = (uu::int)";
+
+test "2*u = (u::int)";
+test "(i + j + 12 + (k::int)) - 15 = y";
+test "(i + j + 12 + (k::int)) - 5 = y";
+
+test "y - b < (b::int)";
+test "y - (3*b + c) < (b::int) - 2*c";
+
+test "(2*x - (u*v) + y) - v*3*u = (w::int)";
+test "(2*x*u*v + (u*v)*4 + y) - v*u*4 = (w::int)";
+test "(2*x*u*v + (u*v)*4 + y) - v*u = (w::int)";
+test "u*v - (x*u*v + (u*v)*4 + y) = (w::int)";
+
+test "(i + j + 12 + (k::int)) = u + 15 + y";
+test "(i + j*2 + 12 + (k::int)) = j + 5 + y";
+
+test "2*y + 3*z + 6*w + 2*y + 3*z + 2*u = 2*y' + 3*z' + 6*w' + 2*y' + 3*z' + u + (vv::int)";
+
+test "a + -(b+c) + b = (d::int)";
+test "a + -(b+c) - b = (d::int)";
+
+(*negative numerals*)
+test "(i + j + -2 + (k::int)) - (u + 5 + y) = zz";
+test "(i + j + -3 + (k::int)) < u + 5 + y";
+test "(i + j + 3 + (k::int)) < u + -6 + y";
+test "(i + j + -12 + (k::int)) - 15 = y";
+test "(i + j + 12 + (k::int)) - -15 = y";
+test "(i + j + -12 + (k::int)) - -15 = y";
+*)
+
+Addsimprocs Numeral_Simprocs.cancel_numeral_factors;
+
+(*examples:
+print_depth 22;
+set timing;
+set trace_simp;
+fun test s = (Goal s; by (Simp_tac 1));
+
+test "9*x = 12 * (y::int)";
+test "(9*x) div (12 * (y::int)) = z";
+test "9*x < 12 * (y::int)";
+test "9*x <= 12 * (y::int)";
+
+test "-99*x = 132 * (y::int)";
+test "(-99*x) div (132 * (y::int)) = z";
+test "-99*x < 132 * (y::int)";
+test "-99*x <= 132 * (y::int)";
+
+test "999*x = -396 * (y::int)";
+test "(999*x) div (-396 * (y::int)) = z";
+test "999*x < -396 * (y::int)";
+test "999*x <= -396 * (y::int)";
+
+test "-99*x = -81 * (y::int)";
+test "(-99*x) div (-81 * (y::int)) = z";
+test "-99*x <= -81 * (y::int)";
+test "-99*x < -81 * (y::int)";
+
+test "-2 * x = -1 * (y::int)";
+test "-2 * x = -(y::int)";
+test "(-2 * x) div (-1 * (y::int)) = z";
+test "-2 * x < -(y::int)";
+test "-2 * x <= -1 * (y::int)";
+test "-x < -23 * (y::int)";
+test "-x <= -23 * (y::int)";
+*)
+
+(*And the same examples for fields such as rat or real:
+test "0 <= (y::rat) * -2";
+test "9*x = 12 * (y::rat)";
+test "(9*x) / (12 * (y::rat)) = z";
+test "9*x < 12 * (y::rat)";
+test "9*x <= 12 * (y::rat)";
+
+test "-99*x = 132 * (y::rat)";
+test "(-99*x) / (132 * (y::rat)) = z";
+test "-99*x < 132 * (y::rat)";
+test "-99*x <= 132 * (y::rat)";
+
+test "999*x = -396 * (y::rat)";
+test "(999*x) / (-396 * (y::rat)) = z";
+test "999*x < -396 * (y::rat)";
+test "999*x <= -396 * (y::rat)";
+
+test "(- ((2::rat) * x) <= 2 * y)";
+test "-99*x = -81 * (y::rat)";
+test "(-99*x) / (-81 * (y::rat)) = z";
+test "-99*x <= -81 * (y::rat)";
+test "-99*x < -81 * (y::rat)";
+
+test "-2 * x = -1 * (y::rat)";
+test "-2 * x = -(y::rat)";
+test "(-2 * x) / (-1 * (y::rat)) = z";
+test "-2 * x < -(y::rat)";
+test "-2 * x <= -1 * (y::rat)";
+test "-x < -23 * (y::rat)";
+test "-x <= -23 * (y::rat)";
+*)
+
+Addsimprocs Numeral_Simprocs.cancel_factors;
+
+
+(*examples:
+print_depth 22;
+set timing;
+set trace_simp;
+fun test s = (Goal s; by (Asm_simp_tac 1));
+
+test "x*k = k*(y::int)";
+test "k = k*(y::int)";
+test "a*(b*c) = (b::int)";
+test "a*(b*c) = d*(b::int)*(x*a)";
+
+test "(x*k) div (k*(y::int)) = (uu::int)";
+test "(k) div (k*(y::int)) = (uu::int)";
+test "(a*(b*c)) div ((b::int)) = (uu::int)";
+test "(a*(b*c)) div (d*(b::int)*(x*a)) = (uu::int)";
+*)
+
+(*And the same examples for fields such as rat or real:
+print_depth 22;
+set timing;
+set trace_simp;
+fun test s = (Goal s; by (Asm_simp_tac 1));
+
+test "x*k = k*(y::rat)";
+test "k = k*(y::rat)";
+test "a*(b*c) = (b::rat)";
+test "a*(b*c) = d*(b::rat)*(x*a)";
+
+
+test "(x*k) / (k*(y::rat)) = (uu::rat)";
+test "(k) / (k*(y::rat)) = (uu::rat)";
+test "(a*(b*c)) / ((b::rat)) = (uu::rat)";
+test "(a*(b*c)) / (d*(b::rat)*(x*a)) = (uu::rat)";
+
+(*FIXME: what do we do about this?*)
+test "a*(b*c)/(y*z) = d*(b::rat)*(x*a)/z";
+*)
--- a/src/HOL/Tools/rat_arith.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/rat_arith.ML Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title: HOL/Real/rat_arith.ML
- ID: $Id$
Author: Lawrence C Paulson
Copyright 2004 University of Cambridge
@@ -10,8 +9,6 @@
local
-val simprocs = field_cancel_numeral_factors
-
val simps =
[@{thm order_less_irrefl}, @{thm neg_less_iff_less}, @{thm True_implies_equals},
read_instantiate @{context} [(("a", 0), "(number_of ?v)")] @{thm right_distrib},
@@ -42,8 +39,8 @@
lessD = lessD, (*Can't change lessD: the rats are dense!*)
neqE = neqE,
simpset = simpset addsimps simps
- addsimprocs simprocs}) #>
- arith_inj_const (@{const_name of_nat}, @{typ "nat => rat"}) #>
- arith_inj_const (@{const_name of_int}, @{typ "int => rat"})
+ addsimprocs Numeral_Simprocs.field_cancel_numeral_factors}) #>
+ Lin_Arith.add_inj_const (@{const_name of_nat}, @{typ "nat => rat"}) #>
+ Lin_Arith.add_inj_const (@{const_name of_int}, @{typ "int => rat"})
end;
--- a/src/HOL/Tools/real_arith.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/real_arith.ML Mon May 11 17:20:52 2009 +0200
@@ -36,7 +36,7 @@
lessD = lessD, (*Can't change lessD: the reals are dense!*)
neqE = neqE,
simpset = simpset addsimps simps}) #>
- arith_inj_const (@{const_name real}, HOLogic.natT --> HOLogic.realT) #>
- arith_inj_const (@{const_name real}, HOLogic.intT --> HOLogic.realT)
+ Lin_Arith.add_inj_const (@{const_name real}, HOLogic.natT --> HOLogic.realT) #>
+ Lin_Arith.add_inj_const (@{const_name real}, HOLogic.intT --> HOLogic.realT)
end;
--- a/src/HOL/Tools/recfun_codegen.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/recfun_codegen.ML Mon May 11 17:20:52 2009 +0200
@@ -25,13 +25,13 @@
fun add_thm NONE thm thy = Code.add_eqn thm thy
| add_thm (SOME module_name) thm thy =
- case Code_Unit.warning_thm (Code_Unit.mk_eqn thy) thm
- of SOME (thm', _) => let val c = Code_Unit.const_eqn thm'
- in thy
- |> ModuleData.map (Symtab.update (c, module_name))
- |> Code.add_eqn thm'
- end
- | NONE => Code.add_eqn thm thy;
+ let
+ val (thm', _) = Code_Unit.mk_eqn thy (K false) (thm, true)
+ in
+ thy
+ |> ModuleData.map (Symtab.update (Code_Unit.const_eqn thy thm', module_name))
+ |> Code.add_eqn thm'
+ end;
fun meta_eq_to_obj_eq thy thm =
let
@@ -57,9 +57,8 @@
val thms = Code.these_raw_eqns thy c'
|> map_filter (fn (thm, linear) => if linear then SOME thm else NONE)
|> expand_eta thy
- |> map (AxClass.overload thy)
|> map_filter (meta_eq_to_obj_eq thy)
- |> Code_Unit.norm_varnames thy Code_Name.purify_tvar Code_Name.purify_var
+ |> Code_Unit.norm_varnames thy
|> map (rpair opt_name)
in if null thms then NONE else SOME thms end;
--- a/src/HOL/Tools/res_reconstruct.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/res_reconstruct.ML Mon May 11 17:20:52 2009 +0200
@@ -16,10 +16,10 @@
val setup: Context.theory -> Context.theory
(* extracting lemma list*)
val find_failure: string -> string option
- val lemma_list_dfg: string * string vector * Proof.context * Thm.thm * int -> string
- val lemma_list_tstp: string * string vector * Proof.context * Thm.thm * int -> string
+ val lemma_list_dfg: string -> string * string vector * Proof.context * Thm.thm * int -> string
+ val lemma_list_tstp: string -> string * string vector * Proof.context * Thm.thm * int -> string
(* structured proofs *)
- val structured_proof: string * string vector * Proof.context * Thm.thm * int -> string
+ val structured_proof: string -> string * string vector * Proof.context * Thm.thm * int -> string
end;
structure ResReconstruct : RES_RECONSTRUCT =
@@ -103,7 +103,7 @@
(*If string s has the prefix s1, return the result of deleting it.*)
fun strip_prefix s1 s =
- if String.isPrefix s1 s
+ if String.isPrefix s1 s
then SOME (ResClause.undo_ascii_of (String.extract (s, size s1, NONE)))
else NONE;
@@ -278,10 +278,10 @@
in #1 (fold_map (decode_tstp vt0) tuples ctxt) end;
(** Finding a matching assumption. The literals may be permuted, and variable names
- may disagree. We have to try all combinations of literals (quadratic!) and
+ may disagree. We have to try all combinations of literals (quadratic!) and
match up the variable names consistently. **)
-fun strip_alls_aux n (Const("all",_)$Abs(a,T,t)) =
+fun strip_alls_aux n (Const("all",_)$Abs(a,T,t)) =
strip_alls_aux (n+1) (subst_bound (Var ((a,n), T), t))
| strip_alls_aux _ t = t;
@@ -292,20 +292,20 @@
(*Ignore types: they are not to be trusted...*)
fun match_literal (t1$u1) (t2$u2) env =
match_literal t1 t2 (match_literal u1 u2 env)
- | match_literal (Abs (_,_,t1)) (Abs (_,_,t2)) env =
+ | match_literal (Abs (_,_,t1)) (Abs (_,_,t2)) env =
match_literal t1 t2 env
- | match_literal (Bound i1) (Bound i2) env =
+ | match_literal (Bound i1) (Bound i2) env =
if i1=i2 then env else raise MATCH_LITERAL
- | match_literal (Const(a1,_)) (Const(a2,_)) env =
+ | match_literal (Const(a1,_)) (Const(a2,_)) env =
if a1=a2 then env else raise MATCH_LITERAL
- | match_literal (Free(a1,_)) (Free(a2,_)) env =
+ | match_literal (Free(a1,_)) (Free(a2,_)) env =
if a1=a2 then env else raise MATCH_LITERAL
| match_literal (Var(ix1,_)) (Var(ix2,_)) env = insert (op =) (ix1,ix2) env
| match_literal _ _ env = raise MATCH_LITERAL;
(*Checking that all variable associations are unique. The list env contains no
repetitions, but does it contain say (x,y) and (y,y)? *)
-fun good env =
+fun good env =
let val (xs,ys) = ListPair.unzip env
in not (has_duplicates (op=) xs orelse has_duplicates (op=) ys) end;
@@ -316,15 +316,15 @@
let fun match1 us [] = false
| match1 us (t::ts) =
let val env' = match_literal lit t env
- in (good env' andalso matches_aux env' lits (us@ts)) orelse
- match1 (t::us) ts
+ in (good env' andalso matches_aux env' lits (us@ts)) orelse
+ match1 (t::us) ts
end
handle MATCH_LITERAL => match1 (t::us) ts
- in match1 [] ts end;
+ in match1 [] ts end;
(*Is this length test useful?*)
-fun matches (lits1,lits2) =
- length lits1 = length lits2 andalso
+fun matches (lits1,lits2) =
+ length lits1 = length lits2 andalso
matches_aux [] (map Envir.eta_contract lits1) (map Envir.eta_contract lits2);
fun permuted_clause t =
@@ -408,7 +408,7 @@
if eq_types t orelse not (null (Term.add_tvars t [])) orelse
exists_subterm bad_free t orelse
(not (null lines) andalso (*final line can't be deleted for these reasons*)
- (length deps < 2 orelse nlines mod (Config.get ctxt modulus) <> 0))
+ (length deps < 2 orelse nlines mod (Config.get ctxt modulus) <> 0))
then (nlines+1, map (replace_deps (lno, deps)) lines) (*Delete line*)
else (nlines+1, (lno, t, deps) :: lines);
@@ -467,7 +467,7 @@
val failure_strings_remote = ["Remote-script could not extract proof"];
fun find_failure proof =
let val failures =
- map_filter (fn s => if String.isSubstring s proof then SOME s else NONE)
+ map_filter (fn s => if String.isSubstring s proof then SOME s else NONE)
(failure_strings_E @ failure_strings_vampire @ failure_strings_SPASS @ failure_strings_remote)
in if null failures then NONE else SOME (hd failures) end;
@@ -481,7 +481,7 @@
"Formulae used in the proof"];
fun get_proof_extract proof =
let
- (*splits to_split by the first possible of a list of splitters*)
+ (*splits to_split by the first possible of a list of splitters*)
fun first_field_any [] to_split = NONE
| first_field_any (splitter::splitters) to_split =
let
@@ -493,10 +493,10 @@
val (proofextract:string, c:string) = valOf (first_field_any end_proof_strings b)
in proofextract end;
- (* === EXTRACTING LEMMAS === *)
+ (* === EXTRACTING LEMMAS === *)
(* lines have the form "cnf(108, axiom, ...",
the number (108) has to be extracted)*)
- fun get_step_nums_tstp proofextract =
+ fun get_step_nums_tstp proofextract =
let val toks = String.tokens (not o Char.isAlphaNum)
fun inputno ("cnf"::ntok::"axiom"::_) = Int.fromString ntok
| inputno _ = NONE
@@ -513,47 +513,56 @@
val lines = split_lines proofextract
in List.mapPartial (inputno o toks) lines end
- (*extracting lemmas from tstp-output between the lines from above*)
- fun extract_lemmas get_step_nums (proof, thm_names, _, _, _) =
+ (*extracting lemmas from tstp-output between the lines from above*)
+ fun extract_lemmas get_step_nums (proof, thm_names, _, _, _) =
let
(* get the names of axioms from their numbers*)
fun get_axiom_names thm_names step_nums =
let
fun is_axiom n = n <= Vector.length thm_names
fun getname i = Vector.sub(thm_names, i-1)
- in
+ in
sort_distinct string_ord (filter (fn x => x <> "??.unknown") (map getname (filter is_axiom step_nums)))
end
val proofextract = get_proof_extract proof
- in
+ in
get_axiom_names thm_names (get_step_nums proofextract)
end;
- (* metis-command *)
- fun metis_line [] = "apply metis"
- | metis_line xs = "apply (metis " ^ space_implode " " xs ^ ")"
-
- (*Used to label theorems chained into the sledgehammer call*)
- val chained_hint = "CHAINED";
- fun sendback_metis_nochained lemmas =
- let val nochained = filter_out (fn y => y = chained_hint)
- in (Markup.markup Markup.sendback o metis_line) (nochained lemmas) end
- fun lemma_list_tstp result = sendback_metis_nochained (extract_lemmas get_step_nums_tstp result);
- fun lemma_list_dfg result = sendback_metis_nochained (extract_lemmas get_step_nums_dfg result);
-
- (* === Extracting structured Isar-proof === *)
- fun structured_proof (result as (proof, thm_names, ctxt, goal, subgoalno)) =
- let
- (*Could use split_lines, but it can return blank lines...*)
- val lines = String.tokens (equal #"\n");
- val nospaces = String.translate (fn c => if Char.isSpace c then "" else str c)
- val proofextract = get_proof_extract proof
- val cnfs = filter (String.isPrefix "cnf(") (map nospaces (lines proofextract))
- val one_line_proof = lemma_list_tstp result
- val structured = if chained_hint mem_string (String.tokens (fn c => c = #" ") one_line_proof) then ""
- else decode_tstp_file cnfs ctxt goal subgoalno thm_names
- in
- one_line_proof ^ "\n\n" ^ (Markup.markup Markup.sendback) structured
- end
+ (* metis-command *)
+ fun metis_line [] = "apply metis"
+ | metis_line xs = "apply (metis " ^ space_implode " " xs ^ ")"
+
+ (* atp_minimize [atp=<prover>] <lemmas> *)
+ fun minimize_line _ [] = ""
+ | minimize_line name lemmas = "For minimizing the number of lemmas try this command:\n" ^
+ (Markup.markup Markup.sendback) ("atp_minimize [atp=" ^ name ^ "] " ^ space_implode " " lemmas)
- end;
+ (*Used to label theorems chained into the sledgehammer call*)
+ val chained_hint = "CHAINED";
+ fun sendback_metis_nochained lemmas =
+ let val nochained = filter_out (fn y => y = chained_hint)
+ in (Markup.markup Markup.sendback o metis_line) (nochained lemmas) end
+ fun lemma_list_tstp name result =
+ let val lemmas = extract_lemmas get_step_nums_tstp result
+ in sendback_metis_nochained lemmas ^ "\n" ^ minimize_line name lemmas end;
+ fun lemma_list_dfg name result =
+ let val lemmas = extract_lemmas get_step_nums_dfg result
+ in sendback_metis_nochained lemmas ^ "\n" ^ minimize_line name lemmas end;
+
+ (* === Extracting structured Isar-proof === *)
+ fun structured_proof name (result as (proof, thm_names, ctxt, goal, subgoalno)) =
+ let
+ (*Could use split_lines, but it can return blank lines...*)
+ val lines = String.tokens (equal #"\n");
+ val nospaces = String.translate (fn c => if Char.isSpace c then "" else str c)
+ val proofextract = get_proof_extract proof
+ val cnfs = filter (String.isPrefix "cnf(") (map nospaces (lines proofextract))
+ val one_line_proof = lemma_list_tstp name result
+ val structured = if chained_hint mem_string (String.tokens (fn c => c = #" ") one_line_proof) then ""
+ else decode_tstp_file cnfs ctxt goal subgoalno thm_names
+ in
+ one_line_proof ^ "\n\n" ^ (Markup.markup Markup.sendback) structured
+ end
+
+end;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Tools/string_code.ML Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,88 @@
+(* Author: Florian Haftmann, TU Muenchen
+
+Code generation for character and string literals.
+*)
+
+signature STRING_CODE =
+sig
+ val add_literal_list_string: string -> theory -> theory
+ val add_literal_char: string -> theory -> theory
+ val add_literal_message: string -> theory -> theory
+end;
+
+structure String_Code : STRING_CODE =
+struct
+
+open Basic_Code_Thingol;
+
+fun decode_char nibbles' tt =
+ let
+ fun idx c = find_index (curry (op =) c) nibbles';
+ fun decode ~1 _ = NONE
+ | decode _ ~1 = NONE
+ | decode n m = SOME (chr (n * 16 + m));
+ in case tt
+ of (IConst (c1, _), IConst (c2, _)) => decode (idx c1) (idx c2)
+ | _ => NONE
+ end;
+
+fun implode_string char' nibbles' mk_char mk_string ts =
+ let
+ fun implode_char (IConst (c, _) `$ t1 `$ t2) =
+ if c = char' then decode_char nibbles' (t1, t2) else NONE
+ | implode_char _ = NONE;
+ val ts' = map_filter implode_char ts;
+ in if length ts = length ts'
+ then (SOME o Code_Printer.str o mk_string o implode) ts'
+ else NONE
+ end;
+
+val cs_nibbles = [@{const_name Nibble0}, @{const_name Nibble1},
+ @{const_name Nibble2}, @{const_name Nibble3},
+ @{const_name Nibble4}, @{const_name Nibble5},
+ @{const_name Nibble6}, @{const_name Nibble7},
+ @{const_name Nibble8}, @{const_name Nibble9},
+ @{const_name NibbleA}, @{const_name NibbleB},
+ @{const_name NibbleC}, @{const_name NibbleD},
+ @{const_name NibbleE}, @{const_name NibbleF}];
+val cs_summa = [@{const_name Nil}, @{const_name Cons}, @{const_name Char}] @ cs_nibbles;
+
+fun add_literal_list_string target =
+ let
+ fun pretty literals (nil' :: cons' :: char' :: nibbles') pr thm vars fxy [(t1, _), (t2, _)] =
+ case Option.map (cons t1) (List_Code.implode_list nil' cons' t2)
+ of SOME ts => (case implode_string char' nibbles'
+ (Code_Printer.literal_char literals) (Code_Printer.literal_string literals) ts
+ of SOME p => p
+ | NONE =>
+ Code_Printer.literal_list literals (map (pr vars Code_Printer.NOBR) ts))
+ | NONE =>
+ List_Code.default_list (Code_Printer.infix_cons literals) (pr vars) fxy t1 t2;
+ in Code_Target.add_syntax_const target
+ @{const_name Cons} (SOME (2, (cs_summa, pretty)))
+ end;
+
+fun add_literal_char target =
+ let
+ fun pretty literals nibbles' _ thm _ _ [(t1, _), (t2, _)] =
+ case decode_char nibbles' (t1, t2)
+ of SOME c => (Code_Printer.str o Code_Printer.literal_char literals) c
+ | NONE => Code_Printer.nerror thm "Illegal character expression";
+ in Code_Target.add_syntax_const target
+ @{const_name Char} (SOME (2, (cs_nibbles, pretty)))
+ end;
+
+fun add_literal_message target =
+ let
+ fun pretty literals (nil' :: cons' :: char' :: nibbles') _ thm _ _ [(t, _)] =
+ case List_Code.implode_list nil' cons' t
+ of SOME ts => (case implode_string char' nibbles'
+ (Code_Printer.literal_char literals) (Code_Printer.literal_string literals) ts
+ of SOME p => p
+ | NONE => Code_Printer.nerror thm "Illegal message expression")
+ | NONE => Code_Printer.nerror thm "Illegal message expression";
+ in Code_Target.add_syntax_const target
+ @{const_name STR} (SOME (1, (cs_summa, pretty)))
+ end;
+
+end;
--- a/src/HOL/Tools/string_syntax.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/string_syntax.ML Mon May 11 17:20:52 2009 +0200
@@ -15,12 +15,14 @@
(* nibble *)
+val nib_prefix = "String.nibble.";
+
val mk_nib =
- Syntax.Constant o unprefix "List.nibble." o
+ Syntax.Constant o unprefix nib_prefix o
fst o Term.dest_Const o HOLogic.mk_nibble;
fun dest_nib (Syntax.Constant c) =
- HOLogic.dest_nibble (Const ("List.nibble." ^ c, dummyT))
+ HOLogic.dest_nibble (Const (nib_prefix ^ c, dummyT))
handle TERM _ => raise Match;
--- a/src/HOL/Tools/typecopy_package.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Tools/typecopy_package.ML Mon May 11 17:20:52 2009 +0200
@@ -150,7 +150,7 @@
THEN ALLGOALS (rtac @{thm refl})) def_thm)
|-> (fn def_thm => Code.add_eqn def_thm)
|> `(fn thy => mk_eq_refl thy)
- |-> (fn refl_thm => Code.add_nonlinear_eqn refl_thm)
+ |-> (fn refl_thm => Code.add_nbe_eqn refl_thm)
end;
val setup =
--- a/src/HOL/Transcendental.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Transcendental.thy Mon May 11 17:20:52 2009 +0200
@@ -14,7 +14,7 @@
subsection {* Properties of Power Series *}
lemma lemma_realpow_diff:
- fixes y :: "'a::recpower"
+ fixes y :: "'a::monoid_mult"
shows "p \<le> n \<Longrightarrow> y ^ (Suc n - p) = (y ^ (n - p)) * y"
proof -
assume "p \<le> n"
@@ -23,14 +23,14 @@
qed
lemma lemma_realpow_diff_sumr:
- fixes y :: "'a::{recpower,comm_semiring_0}" shows
+ fixes y :: "'a::{comm_semiring_0,monoid_mult}" shows
"(\<Sum>p=0..<Suc n. (x ^ p) * y ^ (Suc n - p)) =
y * (\<Sum>p=0..<Suc n. (x ^ p) * y ^ (n - p))"
by (simp add: setsum_right_distrib lemma_realpow_diff mult_ac
del: setsum_op_ivl_Suc cong: strong_setsum_cong)
lemma lemma_realpow_diff_sumr2:
- fixes y :: "'a::{recpower,comm_ring}" shows
+ fixes y :: "'a::{comm_ring,monoid_mult}" shows
"x ^ (Suc n) - y ^ (Suc n) =
(x - y) * (\<Sum>p=0..<Suc n. (x ^ p) * y ^ (n - p))"
apply (induct n, simp)
@@ -56,7 +56,7 @@
x}, then it sums absolutely for @{term z} with @{term "\<bar>z\<bar> < \<bar>x\<bar>"}.*}
lemma powser_insidea:
- fixes x z :: "'a::{real_normed_field,banach,recpower}"
+ fixes x z :: "'a::{real_normed_field,banach}"
assumes 1: "summable (\<lambda>n. f n * x ^ n)"
assumes 2: "norm z < norm x"
shows "summable (\<lambda>n. norm (f n * z ^ n))"
@@ -108,7 +108,7 @@
qed
lemma powser_inside:
- fixes f :: "nat \<Rightarrow> 'a::{real_normed_field,banach,recpower}" shows
+ fixes f :: "nat \<Rightarrow> 'a::{real_normed_field,banach}" shows
"[| summable (%n. f(n) * (x ^ n)); norm z < norm x |]
==> summable (%n. f(n) * (z ^ n))"
by (rule powser_insidea [THEN summable_norm_cancel])
@@ -347,7 +347,7 @@
done
lemma lemma_termdiff1:
- fixes z :: "'a :: {recpower,comm_ring}" shows
+ fixes z :: "'a :: {monoid_mult,comm_ring}" shows
"(\<Sum>p=0..<m. (((z + h) ^ (m - p)) * (z ^ p)) - (z ^ m)) =
(\<Sum>p=0..<m. (z ^ p) * (((z + h) ^ (m - p)) - (z ^ (m - p))))"
by(auto simp add: algebra_simps power_add [symmetric] cong: strong_setsum_cong)
@@ -357,7 +357,7 @@
by (simp add: setsum_subtractf)
lemma lemma_termdiff2:
- fixes h :: "'a :: {recpower,field}"
+ fixes h :: "'a :: {field}"
assumes h: "h \<noteq> 0" shows
"((z + h) ^ n - z ^ n) / h - of_nat n * z ^ (n - Suc 0) =
h * (\<Sum>p=0..< n - Suc 0. \<Sum>q=0..< n - Suc 0 - p.
@@ -393,7 +393,7 @@
done
lemma lemma_termdiff3:
- fixes h z :: "'a::{real_normed_field,recpower}"
+ fixes h z :: "'a::{real_normed_field}"
assumes 1: "h \<noteq> 0"
assumes 2: "norm z \<le> K"
assumes 3: "norm (z + h) \<le> K"
@@ -433,7 +433,7 @@
qed
lemma lemma_termdiff4:
- fixes f :: "'a::{real_normed_field,recpower} \<Rightarrow>
+ fixes f :: "'a::{real_normed_field} \<Rightarrow>
'b::real_normed_vector"
assumes k: "0 < (k::real)"
assumes le: "\<And>h. \<lbrakk>h \<noteq> 0; norm h < k\<rbrakk> \<Longrightarrow> norm (f h) \<le> K * norm h"
@@ -478,7 +478,7 @@
qed
lemma lemma_termdiff5:
- fixes g :: "'a::{recpower,real_normed_field} \<Rightarrow>
+ fixes g :: "'a::{real_normed_field} \<Rightarrow>
nat \<Rightarrow> 'b::banach"
assumes k: "0 < (k::real)"
assumes f: "summable f"
@@ -507,7 +507,7 @@
text{* FIXME: Long proofs*}
lemma termdiffs_aux:
- fixes x :: "'a::{recpower,real_normed_field,banach}"
+ fixes x :: "'a::{real_normed_field,banach}"
assumes 1: "summable (\<lambda>n. diffs (diffs c) n * K ^ n)"
assumes 2: "norm x < norm K"
shows "(\<lambda>h. \<Sum>n. c n * (((x + h) ^ n - x ^ n) / h
@@ -572,7 +572,7 @@
qed
lemma termdiffs:
- fixes K x :: "'a::{recpower,real_normed_field,banach}"
+ fixes K x :: "'a::{real_normed_field,banach}"
assumes 1: "summable (\<lambda>n. c n * K ^ n)"
assumes 2: "summable (\<lambda>n. (diffs c) n * K ^ n)"
assumes 3: "summable (\<lambda>n. (diffs (diffs c)) n * K ^ n)"
@@ -822,11 +822,11 @@
subsection {* Exponential Function *}
definition
- exp :: "'a \<Rightarrow> 'a::{recpower,real_normed_field,banach}" where
+ exp :: "'a \<Rightarrow> 'a::{real_normed_field,banach}" where
"exp x = (\<Sum>n. x ^ n /\<^sub>R real (fact n))"
lemma summable_exp_generic:
- fixes x :: "'a::{real_normed_algebra_1,recpower,banach}"
+ fixes x :: "'a::{real_normed_algebra_1,banach}"
defines S_def: "S \<equiv> \<lambda>n. x ^ n /\<^sub>R real (fact n)"
shows "summable S"
proof -
@@ -856,7 +856,7 @@
qed
lemma summable_norm_exp:
- fixes x :: "'a::{real_normed_algebra_1,recpower,banach}"
+ fixes x :: "'a::{real_normed_algebra_1,banach}"
shows "summable (\<lambda>n. norm (x ^ n /\<^sub>R real (fact n)))"
proof (rule summable_norm_comparison_test [OF exI, rule_format])
show "summable (\<lambda>n. norm x ^ n /\<^sub>R real (fact n))"
@@ -901,7 +901,7 @@
subsubsection {* Properties of the Exponential Function *}
lemma powser_zero:
- fixes f :: "nat \<Rightarrow> 'a::{real_normed_algebra_1,recpower}"
+ fixes f :: "nat \<Rightarrow> 'a::{real_normed_algebra_1}"
shows "(\<Sum>n. f n * 0 ^ n) = f 0"
proof -
have "(\<Sum>n = 0..<1. f n * 0 ^ n) = (\<Sum>n. f n * 0 ^ n)"
@@ -918,7 +918,7 @@
del: setsum_cl_ivl_Suc)
lemma exp_series_add:
- fixes x y :: "'a::{real_field,recpower}"
+ fixes x y :: "'a::{real_field}"
defines S_def: "S \<equiv> \<lambda>x n. x ^ n /\<^sub>R real (fact n)"
shows "S (x + y) n = (\<Sum>i=0..n. S x i * S y (n - i))"
proof (induct n)
--- a/src/HOL/Transitive_Closure.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Transitive_Closure.thy Mon May 11 17:20:52 2009 +0200
@@ -630,6 +630,140 @@
declare trancl_into_rtrancl [elim]
+subsection {* The power operation on relations *}
+
+text {* @{text "R ^^ n = R O ... O R"}, the n-fold composition of @{text R} *}
+
+overloading
+ relpow == "compow :: nat \<Rightarrow> ('a \<times> 'a) set \<Rightarrow> ('a \<times> 'a) set"
+begin
+
+primrec relpow :: "nat \<Rightarrow> ('a \<times> 'a) set \<Rightarrow> ('a \<times> 'a) set" where
+ "relpow 0 R = Id"
+ | "relpow (Suc n) R = R O (R ^^ n)"
+
+end
+
+lemma rel_pow_1 [simp]:
+ fixes R :: "('a \<times> 'a) set"
+ shows "R ^^ 1 = R"
+ by simp
+
+lemma rel_pow_0_I:
+ "(x, x) \<in> R ^^ 0"
+ by simp
+
+lemma rel_pow_Suc_I:
+ "(x, y) \<in> R ^^ n \<Longrightarrow> (y, z) \<in> R \<Longrightarrow> (x, z) \<in> R ^^ Suc n"
+ by auto
+
+lemma rel_pow_Suc_I2:
+ "(x, y) \<in> R \<Longrightarrow> (y, z) \<in> R ^^ n \<Longrightarrow> (x, z) \<in> R ^^ Suc n"
+ by (induct n arbitrary: z) (simp, fastsimp)
+
+lemma rel_pow_0_E:
+ "(x, y) \<in> R ^^ 0 \<Longrightarrow> (x = y \<Longrightarrow> P) \<Longrightarrow> P"
+ by simp
+
+lemma rel_pow_Suc_E:
+ "(x, z) \<in> R ^^ Suc n \<Longrightarrow> (\<And>y. (x, y) \<in> R ^^ n \<Longrightarrow> (y, z) \<in> R \<Longrightarrow> P) \<Longrightarrow> P"
+ by auto
+
+lemma rel_pow_E:
+ "(x, z) \<in> R ^^ n \<Longrightarrow> (n = 0 \<Longrightarrow> x = z \<Longrightarrow> P)
+ \<Longrightarrow> (\<And>y m. n = Suc m \<Longrightarrow> (x, y) \<in> R ^^ m \<Longrightarrow> (y, z) \<in> R \<Longrightarrow> P)
+ \<Longrightarrow> P"
+ by (cases n) auto
+
+lemma rel_pow_Suc_D2:
+ "(x, z) \<in> R ^^ Suc n \<Longrightarrow> (\<exists>y. (x, y) \<in> R \<and> (y, z) \<in> R ^^ n)"
+ apply (induct n arbitrary: x z)
+ apply (blast intro: rel_pow_0_I elim: rel_pow_0_E rel_pow_Suc_E)
+ apply (blast intro: rel_pow_Suc_I elim: rel_pow_0_E rel_pow_Suc_E)
+ done
+
+lemma rel_pow_Suc_E2:
+ "(x, z) \<in> R ^^ Suc n \<Longrightarrow> (\<And>y. (x, y) \<in> R \<Longrightarrow> (y, z) \<in> R ^^ n \<Longrightarrow> P) \<Longrightarrow> P"
+ by (blast dest: rel_pow_Suc_D2)
+
+lemma rel_pow_Suc_D2':
+ "\<forall>x y z. (x, y) \<in> R ^^ n \<and> (y, z) \<in> R \<longrightarrow> (\<exists>w. (x, w) \<in> R \<and> (w, z) \<in> R ^^ n)"
+ by (induct n) (simp_all, blast)
+
+lemma rel_pow_E2:
+ "(x, z) \<in> R ^^ n \<Longrightarrow> (n = 0 \<Longrightarrow> x = z \<Longrightarrow> P)
+ \<Longrightarrow> (\<And>y m. n = Suc m \<Longrightarrow> (x, y) \<in> R \<Longrightarrow> (y, z) \<in> R ^^ m \<Longrightarrow> P)
+ \<Longrightarrow> P"
+ apply (cases n, simp)
+ apply (cut_tac n=nat and R=R in rel_pow_Suc_D2', simp, blast)
+ done
+
+lemma rtrancl_imp_UN_rel_pow:
+ assumes "p \<in> R^*"
+ shows "p \<in> (\<Union>n. R ^^ n)"
+proof (cases p)
+ case (Pair x y)
+ with assms have "(x, y) \<in> R^*" by simp
+ then have "(x, y) \<in> (\<Union>n. R ^^ n)" proof induct
+ case base show ?case by (blast intro: rel_pow_0_I)
+ next
+ case step then show ?case by (blast intro: rel_pow_Suc_I)
+ qed
+ with Pair show ?thesis by simp
+qed
+
+lemma rel_pow_imp_rtrancl:
+ assumes "p \<in> R ^^ n"
+ shows "p \<in> R^*"
+proof (cases p)
+ case (Pair x y)
+ with assms have "(x, y) \<in> R ^^ n" by simp
+ then have "(x, y) \<in> R^*" proof (induct n arbitrary: x y)
+ case 0 then show ?case by simp
+ next
+ case Suc then show ?case
+ by (blast elim: rel_pow_Suc_E intro: rtrancl_into_rtrancl)
+ qed
+ with Pair show ?thesis by simp
+qed
+
+lemma rtrancl_is_UN_rel_pow:
+ "R^* = (\<Union>n. R ^^ n)"
+ by (blast intro: rtrancl_imp_UN_rel_pow rel_pow_imp_rtrancl)
+
+lemma rtrancl_power:
+ "p \<in> R^* \<longleftrightarrow> (\<exists>n. p \<in> R ^^ n)"
+ by (simp add: rtrancl_is_UN_rel_pow)
+
+lemma trancl_power:
+ "p \<in> R^+ \<longleftrightarrow> (\<exists>n > 0. p \<in> R ^^ n)"
+ apply (cases p)
+ apply simp
+ apply (rule iffI)
+ apply (drule tranclD2)
+ apply (clarsimp simp: rtrancl_is_UN_rel_pow)
+ apply (rule_tac x="Suc n" in exI)
+ apply (clarsimp simp: rel_comp_def)
+ apply fastsimp
+ apply clarsimp
+ apply (case_tac n, simp)
+ apply clarsimp
+ apply (drule rel_pow_imp_rtrancl)
+ apply (drule rtrancl_into_trancl1) apply auto
+ done
+
+lemma rtrancl_imp_rel_pow:
+ "p \<in> R^* \<Longrightarrow> \<exists>n. p \<in> R ^^ n"
+ by (auto dest: rtrancl_imp_UN_rel_pow)
+
+lemma single_valued_rel_pow:
+ fixes R :: "('a * 'a) set"
+ shows "single_valued R \<Longrightarrow> single_valued (R ^^ n)"
+ apply (induct n arbitrary: R)
+ apply simp_all
+ apply (rule single_valuedI)
+ apply (fast dest: single_valuedD elim: rel_pow_Suc_E)
+ done
subsection {* Setup of transitivity reasoner *}
--- a/src/HOL/Typerep.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Typerep.thy Mon May 11 17:20:52 2009 +0200
@@ -1,17 +1,15 @@
-(* Title: HOL/Typerep.thy
- Author: Florian Haftmann, TU Muenchen
-*)
+(* Author: Florian Haftmann, TU Muenchen *)
header {* Reflecting Pure types into HOL *}
theory Typerep
-imports Plain List Code_Message
+imports Plain String
begin
datatype typerep = Typerep message_string "typerep list"
class typerep =
- fixes typerep :: "'a\<Colon>{} itself \<Rightarrow> typerep"
+ fixes typerep :: "'a itself \<Rightarrow> typerep"
begin
definition typerep_of :: "'a \<Rightarrow> typerep" where
@@ -42,7 +40,7 @@
struct
fun mk f (Type (tyco, tys)) =
- @{term Typerep} $ Message_String.mk tyco
+ @{term Typerep} $ HOLogic.mk_message_string tyco
$ HOLogic.mk_list @{typ typerep} (map (mk f) tys)
| mk f (TFree v) =
f v;
@@ -79,8 +77,7 @@
*}
setup {*
- Typerep.add_def @{type_name prop}
- #> Typerep.add_def @{type_name fun}
+ Typerep.add_def @{type_name fun}
#> Typerep.add_def @{type_name itself}
#> Typerep.add_def @{type_name bool}
#> TypedefPackage.interpretation Typerep.perhaps_add_def
@@ -92,12 +89,12 @@
by (auto simp add: equals_eq [symmetric] list_all2_eq [symmetric])
code_type typerep
- (SML "Term.typ")
+ (Eval "Term.typ")
code_const Typerep
- (SML "Term.Type/ (_, _)")
+ (Eval "Term.Type/ (_, _)")
-code_reserved SML Term
+code_reserved Eval Term
hide (open) const typerep Typerep
--- a/src/HOL/UNITY/Comp.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/UNITY/Comp.thy Mon May 11 17:20:52 2009 +0200
@@ -15,14 +15,22 @@
header{*Composition: Basic Primitives*}
-theory Comp imports Union begin
+theory Comp
+imports Union
+begin
-instance program :: (type) ord ..
+instantiation program :: (type) ord
+begin
-defs
- component_def: "F \<le> H == \<exists>G. F\<squnion>G = H"
- strict_component_def: "(F < (H::'a program)) == (F \<le> H & F \<noteq> H)"
+definition
+ component_def: "F \<le> H <-> (\<exists>G. F\<squnion>G = H)"
+definition
+ strict_component_def: "F < (H::'a program) <-> (F \<le> H & F \<noteq> H)"
+
+instance ..
+
+end
constdefs
component_of :: "'a program =>'a program=> bool"
@@ -114,7 +122,7 @@
by (auto simp add: stable_def component_constrains)
(*Used in Guar.thy to show that programs are partially ordered*)
-lemmas program_less_le = strict_component_def [THEN meta_eq_to_obj_eq]
+lemmas program_less_le = strict_component_def
subsection{*The preserves property*}
@@ -229,8 +237,7 @@
apply (blast intro: Join_assoc [symmetric])
done
-lemmas strict_component_of_eq =
- strict_component_of_def [THEN meta_eq_to_obj_eq, standard]
+lemmas strict_component_of_eq = strict_component_of_def
(** localize **)
lemma localize_Init_eq [simp]: "Init (localize v F) = Init F"
--- a/src/HOL/UNITY/Transformers.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/UNITY/Transformers.thy Mon May 11 17:20:52 2009 +0200
@@ -338,10 +338,10 @@
constdefs
wens_single_finite :: "[('a*'a) set, 'a set, nat] => 'a set"
- "wens_single_finite act B k == \<Union>i \<in> atMost k. ((wp act)^i) B"
+ "wens_single_finite act B k == \<Union>i \<in> atMost k. (wp act ^^ i) B"
wens_single :: "[('a*'a) set, 'a set] => 'a set"
- "wens_single act B == \<Union>i. ((wp act)^i) B"
+ "wens_single act B == \<Union>i. (wp act ^^ i) B"
lemma wens_single_Un_eq:
"single_valued act
--- a/src/HOL/Wellfounded.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Wellfounded.thy Mon May 11 17:20:52 2009 +0200
@@ -7,7 +7,7 @@
header {*Well-founded Recursion*}
theory Wellfounded
-imports Finite_Set Transitive_Closure Nat
+imports Finite_Set Transitive_Closure
uses ("Tools/function_package/size.ML")
begin
--- a/src/HOL/Word/BinBoolList.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Word/BinBoolList.thy Mon May 11 17:20:52 2009 +0200
@@ -38,7 +38,7 @@
if y then rbl_add ws x else ws)"
lemma butlast_power:
- "(butlast ^ n) bl = take (length bl - n) bl"
+ "(butlast ^^ n) bl = take (length bl - n) bl"
by (induct n) (auto simp: butlast_take)
lemma bin_to_bl_aux_Pls_minus_simp [simp]:
@@ -370,14 +370,14 @@
done
lemma nth_rest_power_bin [rule_format] :
- "ALL n. bin_nth ((bin_rest ^ k) w) n = bin_nth w (n + k)"
+ "ALL n. bin_nth ((bin_rest ^^ k) w) n = bin_nth w (n + k)"
apply (induct k, clarsimp)
apply clarsimp
apply (simp only: bin_nth.Suc [symmetric] add_Suc)
done
lemma take_rest_power_bin:
- "m <= n ==> take m (bin_to_bl n w) = bin_to_bl m ((bin_rest ^ (n - m)) w)"
+ "m <= n ==> take m (bin_to_bl n w) = bin_to_bl m ((bin_rest ^^ (n - m)) w)"
apply (rule nth_equalityI)
apply simp
apply (clarsimp simp add: nth_bin_to_bl nth_rest_power_bin)
--- a/src/HOL/Word/BinGeneral.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Word/BinGeneral.thy Mon May 11 17:20:52 2009 +0200
@@ -439,7 +439,7 @@
apply clarsimp
apply (simp add: bin_last_mod bin_rest_div Bit_def
cong: number_of_False_cong)
- apply (clarsimp simp: zmod_zmult_zmult1 [symmetric]
+ apply (clarsimp simp: mod_mult_mult1 [symmetric]
zmod_zdiv_equality [THEN diff_eq_eq [THEN iffD2 [THEN sym]]])
apply (rule trans [symmetric, OF _ emep1])
apply auto
@@ -822,8 +822,8 @@
by (induct n) auto
lemma bin_rest_power_trunc [rule_format] :
- "(bin_rest ^ k) (bintrunc n bin) =
- bintrunc (n - k) ((bin_rest ^ k) bin)"
+ "(bin_rest ^^ k) (bintrunc n bin) =
+ bintrunc (n - k) ((bin_rest ^^ k) bin)"
by (induct k) (auto simp: bin_rest_trunc)
lemma bin_rest_trunc_i:
@@ -857,7 +857,7 @@
by (rule ext) auto
lemma rco_lem:
- "f o g o f = g o f ==> f o (g o f) ^ n = g ^ n o f"
+ "f o g o f = g o f ==> f o (g o f) ^^ n = g ^^ n o f"
apply (rule ext)
apply (induct_tac n)
apply (simp_all (no_asm))
@@ -867,7 +867,7 @@
apply simp
done
-lemma rco_alt: "(f o g) ^ n o f = f o (g o f) ^ n"
+lemma rco_alt: "(f o g) ^^ n o f = f o (g o f) ^^ n"
apply (rule ext)
apply (induct n)
apply (simp_all add: o_def)
@@ -891,8 +891,9 @@
subsection {* Miscellaneous lemmas *}
-lemmas funpow_minus_simp =
- trans [OF gen_minus [where f = "power f"] funpow_Suc, standard]
+lemma funpow_minus_simp:
+ "0 < n \<Longrightarrow> f ^^ n = f \<circ> f ^^ (n - 1)"
+ by (cases n) simp_all
lemmas funpow_pred_simp [simp] =
funpow_minus_simp [of "number_of bin", simplified nobm1, standard]
--- a/src/HOL/Word/BinOperations.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Word/BinOperations.thy Mon May 11 17:20:52 2009 +0200
@@ -641,7 +641,7 @@
apply (simp add: bin_rest_div zdiv_zmult2_eq)
apply (case_tac b rule: bin_exhaust)
apply simp
- apply (simp add: Bit_def zmod_zmult_zmult1 p1mod22k
+ apply (simp add: Bit_def mod_mult_mult1 p1mod22k
split: bit.split
cong: number_of_False_cong)
done
--- a/src/HOL/Word/Num_Lemmas.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Word/Num_Lemmas.thy Mon May 11 17:20:52 2009 +0200
@@ -45,10 +45,6 @@
apply (simp add: number_of_eq nat_diff_distrib [symmetric])
done
-lemma of_int_power:
- "of_int (a ^ n) = (of_int a ^ n :: 'a :: {recpower, comm_ring_1})"
- by (induct n) (auto simp add: power_Suc)
-
lemma zless2: "0 < (2 :: int)" by arith
lemmas zless2p [simp] = zless2 [THEN zero_less_power]
@@ -66,7 +62,7 @@
apply (safe dest!: even_equiv_def [THEN iffD1])
apply (subst pos_zmod_mult_2)
apply arith
- apply (simp add: zmod_zmult_zmult1)
+ apply (simp add: mod_mult_mult1)
done
lemmas eme1p = emep1 [simplified add_commute]
--- a/src/HOL/Word/TdThs.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Word/TdThs.thy Mon May 11 17:20:52 2009 +0200
@@ -110,7 +110,7 @@
done
lemma fn_comm_power:
- "fa o tr = tr o fr ==> fa ^ n o tr = tr o fr ^ n"
+ "fa o tr = tr o fr ==> fa ^^ n o tr = tr o fr ^^ n"
apply (rule ext)
apply (induct n)
apply (auto dest: fun_cong)
--- a/src/HOL/Word/WordArith.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Word/WordArith.thy Mon May 11 17:20:52 2009 +0200
@@ -701,7 +701,8 @@
apply (erule (2) udvd_decr0)
done
-ML{*Delsimprocs cancel_factors*}
+ML {* Delsimprocs Numeral_Simprocs.cancel_factors *}
+
lemma udvd_incr2_K:
"p < a + s ==> a <= a + s ==> K udvd s ==> K udvd p - a ==> a <= p ==>
0 < K ==> p <= p + K & p + K <= a + s"
@@ -717,7 +718,8 @@
apply arith
apply simp
done
-ML{*Delsimprocs cancel_factors*}
+
+ML {* Addsimprocs Numeral_Simprocs.cancel_factors *}
(* links with rbl operations *)
lemma word_succ_rbl:
@@ -794,9 +796,6 @@
instance word :: (len0) order ..
-instance word :: (len) recpower
- by (intro_classes) simp_all
-
(* note that iszero_def is only for class comm_semiring_1_cancel,
which requires word length >= 1, ie 'a :: len word *)
lemma zero_bintrunc:
--- a/src/HOL/Word/WordBitwise.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Word/WordBitwise.thy Mon May 11 17:20:52 2009 +0200
@@ -443,8 +443,10 @@
lemmas test_bit_2p = refl [THEN test_bit_2p', unfolded word_size]
-lemmas nth_w2p = test_bit_2p [unfolded of_int_number_of_eq
- word_of_int [symmetric] Int.of_int_power]
+lemma nth_w2p:
+ "((2\<Colon>'a\<Colon>len word) ^ n) !! m \<longleftrightarrow> m = n \<and> m < len_of TYPE('a\<Colon>len)"
+ unfolding test_bit_2p [symmetric] word_of_int [symmetric]
+ by (simp add: of_int_power)
lemma uint_2p:
"(0::'a::len word) < 2 ^ n ==> uint (2 ^ n::'a::len word) = 2 ^ n"
--- a/src/HOL/Word/WordDefinition.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Word/WordDefinition.thy Mon May 11 17:20:52 2009 +0200
@@ -99,7 +99,7 @@
subsection "Arithmetic operations"
-instantiation word :: (len0) "{number, uminus, minus, plus, one, zero, times, Divides.div, power, ord, bit}"
+instantiation word :: (len0) "{number, uminus, minus, plus, one, zero, times, Divides.div, ord, bit}"
begin
definition
@@ -126,10 +126,6 @@
definition
word_mod_def: "a mod b = word_of_int (uint a mod uint b)"
-primrec power_word where
- "(a\<Colon>'a word) ^ 0 = 1"
- | "(a\<Colon>'a word) ^ Suc n = a * a ^ n"
-
definition
word_number_of_def: "number_of w = word_of_int w"
@@ -157,7 +153,7 @@
instance ..
-end
+end
definition
word_succ :: "'a :: len0 word => 'a word"
@@ -207,10 +203,10 @@
"shiftr1 w = word_of_int (bin_rest (uint w))"
definition
- shiftl_def: "w << n = (shiftl1 ^ n) w"
+ shiftl_def: "w << n = (shiftl1 ^^ n) w"
definition
- shiftr_def: "w >> n = (shiftr1 ^ n) w"
+ shiftr_def: "w >> n = (shiftr1 ^^ n) w"
instance ..
@@ -245,7 +241,7 @@
"bshiftr1 b w == of_bl (b # butlast (to_bl w))"
sshiftr :: "'a :: len word => nat => 'a word" (infixl ">>>" 55)
- "w >>> n == (sshiftr1 ^ n) w"
+ "w >>> n == (sshiftr1 ^^ n) w"
mask :: "nat => 'a::len word"
"mask n == (1 << n) - 1"
@@ -268,7 +264,7 @@
case ys of [] => [] | x # xs => last ys # butlast ys"
rotater :: "nat => 'a list => 'a list"
- "rotater n == rotater1 ^ n"
+ "rotater n == rotater1 ^^ n"
word_rotr :: "nat => 'a :: len0 word => 'a :: len0 word"
"word_rotr n w == of_bl (rotater n (to_bl w))"
@@ -303,7 +299,7 @@
constdefs
-- "Largest representable machine integer."
max_word :: "'a::len word"
- "max_word \<equiv> word_of_int (2^len_of TYPE('a) - 1)"
+ "max_word \<equiv> word_of_int (2 ^ len_of TYPE('a) - 1)"
consts
of_bool :: "bool \<Rightarrow> 'a::len word"
--- a/src/HOL/Word/WordShift.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/Word/WordShift.thy Mon May 11 17:20:52 2009 +0200
@@ -361,14 +361,14 @@
lemma shiftr_no':
"w = number_of bin ==>
- (w::'a::len0 word) >> n = number_of ((bin_rest ^ n) (bintrunc (size w) bin))"
+ (w::'a::len0 word) >> n = number_of ((bin_rest ^^ n) (bintrunc (size w) bin))"
apply clarsimp
apply (rule word_eqI)
apply (auto simp: nth_shiftr nth_rest_power_bin nth_bintr word_size)
done
lemma sshiftr_no':
- "w = number_of bin ==> w >>> n = number_of ((bin_rest ^ n)
+ "w = number_of bin ==> w >>> n = number_of ((bin_rest ^^ n)
(sbintrunc (size w - 1) bin))"
apply clarsimp
apply (rule word_eqI)
--- a/src/HOL/base.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/base.ML Mon May 11 17:20:52 2009 +0200
@@ -1,2 +1,2 @@
(*side-entry for HOL-Base*)
-use_thy "Code_Setup";
+use_thy "HOL";
--- a/src/HOL/ex/Arith_Examples.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ex/Arith_Examples.thy Mon May 11 17:20:52 2009 +0200
@@ -4,7 +4,9 @@
header {* Arithmetic *}
-theory Arith_Examples imports Main begin
+theory Arith_Examples
+imports Main
+begin
text {*
The @{text arith} method is used frequently throughout the Isabelle
@@ -27,7 +29,7 @@
*}
(*
-ML {* set trace_arith; *}
+ML {* set Lin_Arith.trace; *}
*)
subsection {* Splitting of Operators: @{term max}, @{term min}, @{term abs},
@@ -35,87 +37,87 @@
@{term Divides.div} *}
lemma "(i::nat) <= max i j"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(i::int) <= max i j"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "min i j <= (i::nat)"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "min i j <= (i::int)"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "min (i::nat) j <= max i j"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "min (i::int) j <= max i j"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "min (i::nat) j + max i j = i + j"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "min (i::int) j + max i j = i + j"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(i::nat) < j ==> min i j < max i j"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(i::int) < j ==> min i j < max i j"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(0::int) <= abs i"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(i::int) <= abs i"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "abs (abs (i::int)) = abs i"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
text {* Also testing subgoals with bound variables. *}
lemma "!!x. (x::nat) <= y ==> x - y = 0"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "!!x. (x::nat) - y = 0 ==> x <= y"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "!!x. ((x::nat) <= y) = (x - y = 0)"
- by (tactic {* linear_arith_tac @{context} 1 *})
+ by linarith
lemma "[| (x::nat) < y; d < 1 |] ==> x - y = d"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "[| (x::nat) < y; d < 1 |] ==> x - y - x = d - x"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(x::int) < y ==> x - y < 0"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "nat (i + j) <= nat i + nat j"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "i < j ==> nat (i - j) = 0"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(i::nat) mod 0 = i"
(* FIXME: need to replace 0 by its numeral representation *)
apply (subst nat_numeral_0_eq_0 [symmetric])
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(i::nat) mod 1 = 0"
(* FIXME: need to replace 1 by its numeral representation *)
apply (subst nat_numeral_1_eq_1 [symmetric])
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(i::nat) mod 42 <= 41"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(i::int) mod 0 = i"
(* FIXME: need to replace 0 by its numeral representation *)
apply (subst numeral_0_eq_0 [symmetric])
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(i::int) mod 1 = 0"
(* FIXME: need to replace 1 by its numeral representation *)
@@ -130,70 +132,70 @@
oops
lemma "-(i::int) * 1 = 0 ==> i = 0"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "[| (0::int) < abs i; abs i * 1 < abs i * j |] ==> 1 < abs i * j"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
subsection {* Meta-Logic *}
lemma "x < Suc y == x <= y"
- by (tactic {* linear_arith_tac @{context} 1 *})
+ by linarith
lemma "((x::nat) == z ==> x ~= y) ==> x ~= y | z ~= y"
- by (tactic {* linear_arith_tac @{context} 1 *})
+ by linarith
subsection {* Various Other Examples *}
lemma "(x < Suc y) = (x <= y)"
- by (tactic {* linear_arith_tac @{context} 1 *})
+ by linarith
lemma "[| (x::nat) < y; y < z |] ==> x < z"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(x::nat) < y & y < z ==> x < z"
- by (tactic {* linear_arith_tac @{context} 1 *})
+ by linarith
text {* This example involves no arithmetic at all, but is solved by
preprocessing (i.e. NNF normalization) alone. *}
lemma "(P::bool) = Q ==> Q = P"
- by (tactic {* linear_arith_tac @{context} 1 *})
+ by linarith
lemma "[| P = (x = 0); (~P) = (y = 0) |] ==> min (x::nat) y = 0"
- by (tactic {* linear_arith_tac @{context} 1 *})
+ by linarith
lemma "[| P = (x = 0); (~P) = (y = 0) |] ==> max (x::nat) y = x + y"
- by (tactic {* linear_arith_tac @{context} 1 *})
+ by linarith
lemma "[| (x::nat) ~= y; a + 2 = b; a < y; y < b; a < x; x < b |] ==> False"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "[| (x::nat) > y; y > z; z > x |] ==> False"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(x::nat) - 5 > y ==> y < x"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(x::nat) ~= 0 ==> 0 < x"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "[| (x::nat) ~= y; x <= y |] ==> x < y"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "[| (x::nat) < y; P (x - y) |] ==> P 0"
- by (tactic {* linear_arith_tac @{context} 1 *})
+ by linarith
lemma "(x - y) - (x::nat) = (x - x) - y"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "[| (a::nat) < b; c < d |] ==> (a - b) = (c - d)"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "((a::nat) - (b - (c - (d - e)))) = (a - (b - (c - (d - e))))"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(n < m & m < n') | (n < m & m = n') | (n < n' & n' < m) |
(n = n' & n' < m) | (n = m & m < n') |
@@ -218,31 +220,31 @@
text {* Constants. *}
lemma "(0::nat) < 1"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(0::int) < 1"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(47::nat) + 11 < 08 * 15"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
lemma "(47::int) + 11 < 08 * 15"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
text {* Splitting of inequalities of different type. *}
lemma "[| (a::nat) ~= b; (i::int) ~= j; a < 2; b < 2 |] ==>
a + b <= nat (max (abs i) (abs j))"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
text {* Again, but different order. *}
lemma "[| (i::int) ~= j; (a::nat) ~= b; a < 2; b < 2 |] ==>
a + b <= nat (max (abs i) (abs j))"
- by (tactic {* fast_arith_tac @{context} 1 *})
+ by linarith
(*
-ML {* reset trace_arith; *}
+ML {* reset Lin_Arith.trace; *}
*)
end
--- a/src/HOL/ex/BinEx.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ex/BinEx.thy Mon May 11 17:20:52 2009 +0200
@@ -712,38 +712,38 @@
by arith
lemma "!!a::real. a \<le> b ==> c \<le> d ==> x + y < z ==> a + c \<le> b + d"
-by (tactic "fast_arith_tac @{context} 1")
+by linarith
lemma "!!a::real. a < b ==> c < d ==> a - d \<le> b + (-c)"
-by (tactic "fast_arith_tac @{context} 1")
+by linarith
lemma "!!a::real. a \<le> b ==> b + b \<le> c ==> a + a \<le> c"
-by (tactic "fast_arith_tac @{context} 1")
+by linarith
lemma "!!a::real. a + b \<le> i + j ==> a \<le> b ==> i \<le> j ==> a + a \<le> j + j"
-by (tactic "fast_arith_tac @{context} 1")
+by linarith
lemma "!!a::real. a + b < i + j ==> a < b ==> i < j ==> a + a < j + j"
-by (tactic "fast_arith_tac @{context} 1")
+by linarith
lemma "!!a::real. a + b + c \<le> i + j + k \<and> a \<le> b \<and> b \<le> c \<and> i \<le> j \<and> j \<le> k --> a + a + a \<le> k + k + k"
by arith
lemma "!!a::real. a + b + c + d \<le> i + j + k + l ==> a \<le> b ==> b \<le> c
==> c \<le> d ==> i \<le> j ==> j \<le> k ==> k \<le> l ==> a \<le> l"
-by (tactic "fast_arith_tac @{context} 1")
+by linarith
lemma "!!a::real. a + b + c + d \<le> i + j + k + l ==> a \<le> b ==> b \<le> c
==> c \<le> d ==> i \<le> j ==> j \<le> k ==> k \<le> l ==> a + a + a + a \<le> l + l + l + l"
-by (tactic "fast_arith_tac @{context} 1")
+by linarith
lemma "!!a::real. a + b + c + d \<le> i + j + k + l ==> a \<le> b ==> b \<le> c
==> c \<le> d ==> i \<le> j ==> j \<le> k ==> k \<le> l ==> a + a + a + a + a \<le> l + l + l + l + i"
-by (tactic "fast_arith_tac @{context} 1")
+by linarith
lemma "!!a::real. a + b + c + d \<le> i + j + k + l ==> a \<le> b ==> b \<le> c
==> c \<le> d ==> i \<le> j ==> j \<le> k ==> k \<le> l ==> a + a + a + a + a + a \<le> l + l + l + l + i + l"
-by (tactic "fast_arith_tac @{context} 1")
+by linarith
subsection{*Complex Arithmetic*}
--- a/src/HOL/ex/Commutative_Ring_Complete.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ex/Commutative_Ring_Complete.thy Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
-(* ID: $Id$
- Author: Bernhard Haeupler
+(* Author: Bernhard Haeupler
This theory is about of the relative completeness of method comm-ring
method. As long as the reified atomic polynomials of type 'a pol are
@@ -14,7 +13,7 @@
text {* Formalization of normal form *}
fun
- isnorm :: "('a::{comm_ring,recpower}) pol \<Rightarrow> bool"
+ isnorm :: "('a::{comm_ring}) pol \<Rightarrow> bool"
where
"isnorm (Pc c) \<longleftrightarrow> True"
| "isnorm (Pinj i (Pc c)) \<longleftrightarrow> False"
--- a/src/HOL/ex/Formal_Power_Series_Examples.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ex/Formal_Power_Series_Examples.thy Mon May 11 17:20:52 2009 +0200
@@ -11,7 +11,7 @@
section{* The generalized binomial theorem *}
lemma gbinomial_theorem:
- "((a::'a::{ring_char_0, field, division_by_zero, recpower})+b) ^ n = (\<Sum>k=0..n. of_nat (n choose k) * a^k * b^(n-k))"
+ "((a::'a::{ring_char_0, field, division_by_zero})+b) ^ n = (\<Sum>k=0..n. of_nat (n choose k) * a^k * b^(n-k))"
proof-
from E_add_mult[of a b]
have "(E (a + b)) $ n = (E a * E b)$n" by simp
@@ -38,7 +38,7 @@
by (simp add: fps_binomial_def)
lemma fps_binomial_ODE_unique:
- fixes c :: "'a::{field, recpower,ring_char_0}"
+ fixes c :: "'a::{field, ring_char_0}"
shows "fps_deriv a = (fps_const c * a) / (1 + X) \<longleftrightarrow> a = fps_const (a$0) * fps_binomial c"
(is "?lhs \<longleftrightarrow> ?rhs")
proof-
--- a/src/HOL/ex/Groebner_Examples.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ex/Groebner_Examples.thy Mon May 11 17:20:52 2009 +0200
@@ -1,5 +1,4 @@
(* Title: HOL/ex/Groebner_Examples.thy
- ID: $Id$
Author: Amine Chaieb, TU Muenchen
*)
@@ -11,7 +10,7 @@
subsection {* Basic examples *}
-lemma "3 ^ 3 == (?X::'a::{number_ring,recpower})"
+lemma "3 ^ 3 == (?X::'a::{number_ring})"
by sring_norm
lemma "(x - (-2))^5 == ?X::int"
@@ -20,7 +19,7 @@
lemma "(x - (-2))^5 * (y - 78) ^ 8 == ?X::int"
by sring_norm
-lemma "((-3) ^ (Suc (Suc (Suc 0)))) == (X::'a::{number_ring,recpower})"
+lemma "((-3) ^ (Suc (Suc (Suc 0)))) == (X::'a::{number_ring})"
apply (simp only: power_Suc power_0)
apply (simp only: comp_arith)
oops
@@ -47,7 +46,7 @@
by algebra
lemma
- fixes x::"'a::{idom,recpower,number_ring}"
+ fixes x::"'a::{idom,number_ring}"
shows "x^2*y = x^2 & x*y^2 = y^2 \<longleftrightarrow> x=1 & y=1 | x=0 & y=0"
by algebra
@@ -58,7 +57,7 @@
"sq x == x*x"
lemma
- fixes x1 :: "'a::{idom,recpower,number_ring}"
+ fixes x1 :: "'a::{idom,number_ring}"
shows
"(sq x1 + sq x2 + sq x3 + sq x4) * (sq y1 + sq y2 + sq y3 + sq y4) =
sq (x1*y1 - x2*y2 - x3*y3 - x4*y4) +
@@ -68,7 +67,7 @@
by (algebra add: sq_def)
lemma
- fixes p1 :: "'a::{idom,recpower,number_ring}"
+ fixes p1 :: "'a::{idom,number_ring}"
shows
"(sq p1 + sq q1 + sq r1 + sq s1 + sq t1 + sq u1 + sq v1 + sq w1) *
(sq p2 + sq q2 + sq r2 + sq s2 + sq t2 + sq u2 + sq v2 + sq w2)
--- a/src/HOL/ex/NormalForm.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ex/NormalForm.thy Mon May 11 17:20:52 2009 +0200
@@ -1,7 +1,6 @@
-(* Authors: Klaus Aehlig, Tobias Nipkow
-*)
+(* Authors: Klaus Aehlig, Tobias Nipkow *)
-header {* Test of normalization function *}
+header {* Testing implementation of normalization by evaluation *}
theory NormalForm
imports Main Rational
@@ -11,7 +10,6 @@
lemma "p \<longrightarrow> True" by normalization
declare disj_assoc [code nbe]
lemma "((P | Q) | R) = (P | (Q | R))" by normalization
-declare disj_assoc [code del]
lemma "0 + (n::nat) = n" by normalization
lemma "0 + Suc n = Suc n" by normalization
lemma "Suc n + Suc m = n + Suc (Suc m)" by normalization
@@ -19,18 +17,13 @@
datatype n = Z | S n
-consts
- add :: "n \<Rightarrow> n \<Rightarrow> n"
- add2 :: "n \<Rightarrow> n \<Rightarrow> n"
- mul :: "n \<Rightarrow> n \<Rightarrow> n"
- mul2 :: "n \<Rightarrow> n \<Rightarrow> n"
- exp :: "n \<Rightarrow> n \<Rightarrow> n"
-primrec
- "add Z = id"
- "add (S m) = S o add m"
-primrec
- "add2 Z n = n"
- "add2 (S m) n = S(add2 m n)"
+primrec add :: "n \<Rightarrow> n \<Rightarrow> n" where
+ "add Z = id"
+ | "add (S m) = S o add m"
+
+primrec add2 :: "n \<Rightarrow> n \<Rightarrow> n" where
+ "add2 Z n = n"
+ | "add2 (S m) n = S(add2 m n)"
declare add2.simps [code]
lemma [code nbe]: "add2 (add2 n m) k = add2 n (add2 m k)"
@@ -44,15 +37,17 @@
lemma "add2 (add2 (S n) (S m)) (S k) = S(S(S(add2 n (add2 m k))))" by normalization
lemma "add2 (add2 (S n) (add2 (S m) Z)) (S k) = S(S(S(add2 n (add2 m k))))" by normalization
-primrec
- "mul Z = (%n. Z)"
- "mul (S m) = (%n. add (mul m n) n)"
-primrec
- "mul2 Z n = Z"
- "mul2 (S m) n = add2 n (mul2 m n)"
-primrec
- "exp m Z = S Z"
- "exp m (S n) = mul (exp m n) m"
+primrec mul :: "n \<Rightarrow> n \<Rightarrow> n" where
+ "mul Z = (%n. Z)"
+ | "mul (S m) = (%n. add (mul m n) n)"
+
+primrec mul2 :: "n \<Rightarrow> n \<Rightarrow> n" where
+ "mul2 Z n = Z"
+ | "mul2 (S m) n = add2 n (mul2 m n)"
+
+primrec exp :: "n \<Rightarrow> n \<Rightarrow> n" where
+ "exp m Z = S Z"
+ | "exp m (S n) = mul (exp m n) m"
lemma "mul2 (S(S(S(S(S Z))))) (S(S(S Z))) = S(S(S(S(S(S(S(S(S(S(S(S(S(S(S Z))))))))))))))" by normalization
lemma "mul (S(S(S(S(S Z))))) (S(S(S Z))) = S(S(S(S(S(S(S(S(S(S(S(S(S(S(S Z))))))))))))))" by normalization
--- a/src/HOL/ex/Numeral.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ex/Numeral.thy Mon May 11 17:20:52 2009 +0200
@@ -14,32 +14,26 @@
text {* Increment function for type @{typ num} *}
-primrec
- inc :: "num \<Rightarrow> num"
-where
+primrec inc :: "num \<Rightarrow> num" where
"inc One = Dig0 One"
| "inc (Dig0 x) = Dig1 x"
| "inc (Dig1 x) = Dig0 (inc x)"
text {* Converting between type @{typ num} and type @{typ nat} *}
-primrec
- nat_of_num :: "num \<Rightarrow> nat"
-where
+primrec nat_of_num :: "num \<Rightarrow> nat" where
"nat_of_num One = Suc 0"
| "nat_of_num (Dig0 x) = nat_of_num x + nat_of_num x"
| "nat_of_num (Dig1 x) = Suc (nat_of_num x + nat_of_num x)"
-primrec
- num_of_nat :: "nat \<Rightarrow> num"
-where
+primrec num_of_nat :: "nat \<Rightarrow> num" where
"num_of_nat 0 = One"
| "num_of_nat (Suc n) = (if 0 < n then inc (num_of_nat n) else One)"
lemma nat_of_num_pos: "0 < nat_of_num x"
by (induct x) simp_all
-lemma nat_of_num_neq_0: " nat_of_num x \<noteq> 0"
+lemma nat_of_num_neq_0: "nat_of_num x \<noteq> 0"
by (induct x) simp_all
lemma nat_of_num_inc: "nat_of_num (inc x) = Suc (nat_of_num x)"
@@ -247,13 +241,24 @@
begin
primrec of_num :: "num \<Rightarrow> 'a" where
- of_num_one [numeral]: "of_num One = 1"
+ of_num_One [numeral]: "of_num One = 1"
| "of_num (Dig0 n) = of_num n + of_num n"
| "of_num (Dig1 n) = of_num n + of_num n + 1"
lemma of_num_inc: "of_num (inc x) = of_num x + 1"
by (induct x) (simp_all add: add_ac)
+lemma of_num_add: "of_num (m + n) = of_num m + of_num n"
+ apply (induct n rule: num_induct)
+ apply (simp_all add: add_One add_inc of_num_inc add_ac)
+ done
+
+lemma of_num_mult: "of_num (m * n) = of_num m * of_num n"
+ apply (induct n rule: num_induct)
+ apply (simp add: mult_One)
+ apply (simp add: mult_inc of_num_add of_num_inc right_distrib)
+ done
+
declare of_num.simps [simp del]
end
@@ -263,16 +268,19 @@
*}
ML {*
-fun mk_num 1 = @{term One}
- | mk_num k =
- let
- val (l, b) = Integer.div_mod k 2;
- val bit = (if b = 0 then @{term Dig0} else @{term Dig1});
- in bit $ (mk_num l) end;
+fun mk_num k =
+ if k > 1 then
+ let
+ val (l, b) = Integer.div_mod k 2;
+ val bit = (if b = 0 then @{term Dig0} else @{term Dig1});
+ in bit $ (mk_num l) end
+ else if k = 1 then @{term One}
+ else error ("mk_num " ^ string_of_int k);
fun dest_num @{term One} = 1
| dest_num (@{term Dig0} $ n) = 2 * dest_num n
- | dest_num (@{term Dig1} $ n) = 2 * dest_num n + 1;
+ | dest_num (@{term Dig1} $ n) = 2 * dest_num n + 1
+ | dest_num t = raise TERM ("dest_num", [t]);
(*FIXME these have to gain proper context via morphisms phi*)
@@ -348,16 +356,15 @@
lemma of_num_plus_one [numeral]:
"of_num n + 1 = of_num (n + One)"
- by (rule sym, induct n) (simp_all add: of_num.simps add_ac)
+ by (simp only: of_num_add of_num_One)
lemma of_num_one_plus [numeral]:
- "1 + of_num n = of_num (n + One)"
- unfolding of_num_plus_one [symmetric] add_commute ..
+ "1 + of_num n = of_num (One + n)"
+ by (simp only: of_num_add of_num_One)
lemma of_num_plus [numeral]:
"of_num m + of_num n = of_num (m + n)"
- by (induct n rule: num_induct)
- (simp_all add: add_One add_inc of_num_one of_num_inc add_ac)
+ unfolding of_num_add ..
lemma of_num_times_one [numeral]:
"of_num n * 1 = of_num n"
@@ -369,9 +376,7 @@
lemma of_num_times [numeral]:
"of_num m * of_num n = of_num (m * n)"
- by (induct n rule: num_induct)
- (simp_all add: of_num_plus [symmetric] mult_One mult_inc
- semiring_class.right_distrib right_distrib of_num_one of_num_inc)
+ unfolding of_num_mult ..
end
@@ -421,21 +426,15 @@
context semiring_char_0
begin
-lemma of_num_eq_iff [numeral]:
- "of_num m = of_num n \<longleftrightarrow> m = n"
+lemma of_num_eq_iff [numeral]: "of_num m = of_num n \<longleftrightarrow> m = n"
unfolding of_nat_of_num [symmetric] nat_of_num_of_num [symmetric]
of_nat_eq_iff num_eq_iff ..
-lemma of_num_eq_one_iff [numeral]:
- "of_num n = 1 \<longleftrightarrow> n = One"
-proof -
- have "of_num n = of_num One \<longleftrightarrow> n = One" unfolding of_num_eq_iff ..
- then show ?thesis by (simp add: of_num_one)
-qed
+lemma of_num_eq_one_iff [numeral]: "of_num n = 1 \<longleftrightarrow> n = One"
+ using of_num_eq_iff [of n One] by (simp add: of_num_One)
-lemma one_eq_of_num_iff [numeral]:
- "1 = of_num n \<longleftrightarrow> n = One"
- unfolding of_num_eq_one_iff [symmetric] by auto
+lemma one_eq_of_num_iff [numeral]: "1 = of_num n \<longleftrightarrow> One = n"
+ using of_num_eq_iff [of One n] by (simp add: of_num_One)
end
@@ -458,19 +457,11 @@
then show ?thesis by (simp add: of_nat_of_num)
qed
-lemma of_num_less_eq_one_iff [numeral]: "of_num n \<le> 1 \<longleftrightarrow> n = One"
-proof -
- have "of_num n \<le> of_num One \<longleftrightarrow> n = One"
- by (cases n) (simp_all add: of_num_less_eq_iff)
- then show ?thesis by (simp add: of_num_one)
-qed
+lemma of_num_less_eq_one_iff [numeral]: "of_num n \<le> 1 \<longleftrightarrow> n \<le> One"
+ using of_num_less_eq_iff [of n One] by (simp add: of_num_One)
lemma one_less_eq_of_num_iff [numeral]: "1 \<le> of_num n"
-proof -
- have "of_num One \<le> of_num n"
- by (cases n) (simp_all add: of_num_less_eq_iff)
- then show ?thesis by (simp add: of_num_one)
-qed
+ using of_num_less_eq_iff [of One n] by (simp add: of_num_One)
lemma of_num_less_iff [numeral]: "of_num m < of_num n \<longleftrightarrow> m < n"
proof -
@@ -480,18 +471,10 @@
qed
lemma of_num_less_one_iff [numeral]: "\<not> of_num n < 1"
-proof -
- have "\<not> of_num n < of_num One"
- by (cases n) (simp_all add: of_num_less_iff)
- then show ?thesis by (simp add: of_num_one)
-qed
+ using of_num_less_iff [of n One] by (simp add: of_num_One)
-lemma one_less_of_num_iff [numeral]: "1 < of_num n \<longleftrightarrow> n \<noteq> One"
-proof -
- have "of_num One < of_num n \<longleftrightarrow> n \<noteq> One"
- by (cases n) (simp_all add: of_num_less_iff)
- then show ?thesis by (simp add: of_num_one)
-qed
+lemma one_less_of_num_iff [numeral]: "1 < of_num n \<longleftrightarrow> One < n"
+ using of_num_less_iff [of One n] by (simp add: of_num_One)
lemma of_num_nonneg [numeral]: "0 \<le> of_num n"
by (induct n) (simp_all add: of_num.simps add_nonneg_nonneg)
@@ -515,13 +498,13 @@
qed
lemma minus_of_num_less_one_iff: "- of_num n < 1"
-using minus_of_num_less_of_num_iff [of n One] by (simp add: of_num_one)
+ using minus_of_num_less_of_num_iff [of n One] by (simp add: of_num_One)
lemma minus_one_less_of_num_iff: "- 1 < of_num n"
-using minus_of_num_less_of_num_iff [of One n] by (simp add: of_num_one)
+ using minus_of_num_less_of_num_iff [of One n] by (simp add: of_num_One)
lemma minus_one_less_one_iff: "- 1 < 1"
-using minus_of_num_less_of_num_iff [of One One] by (simp add: of_num_one)
+ using minus_of_num_less_of_num_iff [of One One] by (simp add: of_num_One)
lemma minus_of_num_le_of_num_iff: "- of_num m \<le> of_num n"
by (simp add: less_imp_le minus_of_num_less_of_num_iff)
@@ -700,7 +683,7 @@
"- of_num n * of_num m = - (of_num n * of_num m)"
"of_num n * - of_num m = - (of_num n * of_num m)"
"- of_num n * - of_num m = of_num n * of_num m"
- by (simp_all add: minus_mult_left [symmetric] minus_mult_right [symmetric])
+ by simp_all
lemma of_int_of_num [numeral]: "of_int (of_num n) = of_num n"
by (induct n)
@@ -716,38 +699,29 @@
lemma of_num_square: "of_num (square x) = of_num x * of_num x"
by (induct x)
- (simp_all add: of_num.simps of_num_plus [symmetric] algebra_simps)
+ (simp_all add: of_num.simps of_num_add algebra_simps)
-lemma of_num_pow:
- "(of_num (pow x y)::'a::{semiring_numeral,recpower}) = of_num x ^ of_num y"
+lemma of_num_pow: "of_num (pow x y) = of_num x ^ of_num y"
by (induct y)
- (simp_all add: of_num.simps of_num_square of_num_times [symmetric]
- power_Suc power_add)
+ (simp_all add: of_num.simps of_num_square of_num_mult power_add)
-lemma power_of_num [numeral]:
- "of_num x ^ of_num y = (of_num (pow x y)::'a::{semiring_numeral,recpower})"
- by (rule of_num_pow [symmetric])
+lemma power_of_num [numeral]: "of_num x ^ of_num y = of_num (pow x y)"
+ unfolding of_num_pow ..
lemma power_zero_of_num [numeral]:
- "0 ^ of_num n = (0::'a::{semiring_0,recpower})"
+ "0 ^ of_num n = (0::'a::semiring_1)"
using of_num_pos [where n=n and ?'a=nat]
by (simp add: power_0_left)
-lemma power_minus_one_double:
- "(- 1) ^ (n + n) = (1::'a::{ring_1,recpower})"
- by (induct n) (simp_all add: power_Suc)
-
lemma power_minus_Dig0 [numeral]:
- fixes x :: "'a::{ring_1,recpower}"
+ fixes x :: "'a::ring_1"
shows "(- x) ^ of_num (Dig0 n) = x ^ of_num (Dig0 n)"
- by (subst power_minus)
- (simp add: of_num.simps power_minus_one_double)
+ by (induct n rule: num_induct) (simp_all add: of_num.simps of_num_inc)
lemma power_minus_Dig1 [numeral]:
- fixes x :: "'a::{ring_1,recpower}"
+ fixes x :: "'a::ring_1"
shows "(- x) ^ of_num (Dig1 n) = - (x ^ of_num (Dig1 n))"
- by (subst power_minus)
- (simp add: of_num.simps power_Suc power_minus_one_double)
+ by (induct n rule: num_induct) (simp_all add: of_num.simps of_num_inc)
declare power_one [numeral]
@@ -823,7 +797,7 @@
lemma one_int_code [code]:
"1 = Pls One"
- by (simp add: of_num_one)
+ by (simp add: of_num_One)
lemma plus_int_code [code]:
"k + 0 = (k::int)"
@@ -832,7 +806,7 @@
"Pls m - Pls n = sub m n"
"Mns m + Mns n = Mns (m + n)"
"Mns m - Mns n = sub n m"
- by (simp_all add: of_num_plus [symmetric])
+ by (simp_all add: of_num_add)
lemma uminus_int_code [code]:
"uminus 0 = (0::int)"
@@ -847,7 +821,7 @@
"Pls m - Mns n = Pls (m + n)"
"Mns m - Pls n = Mns (m + n)"
"Mns m - Mns n = sub n m"
- by (simp_all add: of_num_plus [symmetric])
+ by (simp_all add: of_num_add)
lemma times_int_code [code]:
"k * 0 = (0::int)"
@@ -856,7 +830,7 @@
"Pls m * Mns n = Mns (m * n)"
"Mns m * Pls n = Mns (m * n)"
"Mns m * Mns n = Pls (m * n)"
- by (simp_all add: of_num_times [symmetric])
+ by (simp_all add: of_num_mult)
lemma eq_int_code [code]:
"eq_class.eq 0 (0::int) \<longleftrightarrow> True"
@@ -907,15 +881,109 @@
subsection {* Numeral equations as default simplification rules *}
-text {* TODO. Be more precise here with respect to subsumed facts. Or use named theorems anyway. *}
-declare (in semiring_numeral) numeral [simp]
-declare (in semiring_1) numeral [simp]
-declare (in semiring_char_0) numeral [simp]
-declare (in ring_1) numeral [simp]
+declare (in semiring_numeral) of_num_One [simp]
+declare (in semiring_numeral) of_num_plus_one [simp]
+declare (in semiring_numeral) of_num_one_plus [simp]
+declare (in semiring_numeral) of_num_plus [simp]
+declare (in semiring_numeral) of_num_times [simp]
+
+declare (in semiring_1) of_nat_of_num [simp]
+
+declare (in semiring_char_0) of_num_eq_iff [simp]
+declare (in semiring_char_0) of_num_eq_one_iff [simp]
+declare (in semiring_char_0) one_eq_of_num_iff [simp]
+
+declare (in ordered_semidom) of_num_pos [simp]
+declare (in ordered_semidom) of_num_less_eq_iff [simp]
+declare (in ordered_semidom) of_num_less_eq_one_iff [simp]
+declare (in ordered_semidom) one_less_eq_of_num_iff [simp]
+declare (in ordered_semidom) of_num_less_iff [simp]
+declare (in ordered_semidom) of_num_less_one_iff [simp]
+declare (in ordered_semidom) one_less_of_num_iff [simp]
+declare (in ordered_semidom) of_num_nonneg [simp]
+declare (in ordered_semidom) of_num_less_zero_iff [simp]
+declare (in ordered_semidom) of_num_le_zero_iff [simp]
+
+declare (in ordered_idom) le_signed_numeral_special [simp]
+declare (in ordered_idom) less_signed_numeral_special [simp]
+
+declare (in semiring_1_minus) Dig_of_num_minus_one [simp]
+declare (in semiring_1_minus) Dig_one_minus_of_num [simp]
+
+declare (in ring_1) Dig_plus_uminus [simp]
+declare (in ring_1) of_int_of_num [simp]
+
+declare power_of_num [simp]
+declare power_zero_of_num [simp]
+declare power_minus_Dig0 [simp]
+declare power_minus_Dig1 [simp]
+
+declare Suc_of_num [simp]
+
thm numeral
-text {* Toy examples *}
+subsection {* Simplification Procedures *}
+
+subsubsection {* Reorientation of equalities *}
+
+setup {*
+ ReorientProc.add
+ (fn Const(@{const_name of_num}, _) $ _ => true
+ | Const(@{const_name uminus}, _) $
+ (Const(@{const_name of_num}, _) $ _) => true
+ | _ => false)
+*}
+
+simproc_setup reorient_num ("of_num n = x" | "- of_num m = y") = ReorientProc.proc
+
+subsubsection {* Constant folding for multiplication in semirings *}
+
+context semiring_numeral
+begin
+
+lemma mult_of_num_commute: "x * of_num n = of_num n * x"
+by (induct n)
+ (simp_all only: of_num.simps left_distrib right_distrib mult_1_left mult_1_right)
+
+definition
+ "commutes_with a b \<longleftrightarrow> a * b = b * a"
+
+lemma commutes_with_commute: "commutes_with a b \<Longrightarrow> a * b = b * a"
+unfolding commutes_with_def .
+
+lemma commutes_with_left_commute: "commutes_with a b \<Longrightarrow> a * (b * c) = b * (a * c)"
+unfolding commutes_with_def by (simp only: mult_assoc [symmetric])
+
+lemma commutes_with_numeral: "commutes_with x (of_num n)" "commutes_with (of_num n) x"
+unfolding commutes_with_def by (simp_all add: mult_of_num_commute)
+
+lemmas mult_ac_numeral =
+ mult_assoc
+ commutes_with_commute
+ commutes_with_left_commute
+ commutes_with_numeral
+
+end
+
+ML {*
+structure Semiring_Times_Assoc_Data : ASSOC_FOLD_DATA =
+struct
+ val assoc_ss = HOL_ss addsimps @{thms mult_ac_numeral}
+ val eq_reflection = eq_reflection
+ fun is_numeral (Const(@{const_name of_num}, _) $ _) = true
+ | is_numeral _ = false;
+end;
+
+structure Semiring_Times_Assoc = Assoc_Fold (Semiring_Times_Assoc_Data);
+*}
+
+simproc_setup semiring_assoc_fold' ("(a::'a::semiring_numeral) * b") =
+ {* fn phi => fn ss => fn ct =>
+ Semiring_Times_Assoc.proc ss (Thm.term_of ct) *}
+
+
+subsection {* Toy examples *}
definition "bar \<longleftrightarrow> #4 * #2 + #7 = (#8 :: nat) \<and> #4 * #2 + #7 \<ge> (#8 :: int) - #3"
code_thms bar
--- a/src/HOL/ex/Predicate_Compile.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ex/Predicate_Compile.thy Mon May 11 17:20:52 2009 +0200
@@ -1,8 +1,10 @@
theory Predicate_Compile
-imports Complex_Main Code_Index Lattice_Syntax
+imports Complex_Main Lattice_Syntax Code_Eval
uses "predicate_compile.ML"
begin
+text {* Package setup *}
+
setup {* Predicate_Compile.setup *}
ML {*
@@ -10,34 +12,81 @@
OuterKeyword.thy_goal (OuterParse.term_group >> Predicate_Compile.code_pred_cmd)
*}
-primrec "next" :: "('a Predicate.pred \<Rightarrow> ('a \<times> 'a Predicate.pred) option)
- \<Rightarrow> 'a Predicate.seq \<Rightarrow> ('a \<times> 'a Predicate.pred) option" where
- "next yield Predicate.Empty = None"
- | "next yield (Predicate.Insert x P) = Some (x, P)"
- | "next yield (Predicate.Join P xq) = (case yield P
- of None \<Rightarrow> next yield xq | Some (x, Q) \<Rightarrow> Some (x, Predicate.Seq (\<lambda>_. Predicate.Join Q xq)))"
+
+text {* Experimental code *}
+
+definition pred_map :: "('a \<Rightarrow> 'b) \<Rightarrow> 'a Predicate.pred \<Rightarrow> 'b Predicate.pred" where
+ "pred_map f P = Predicate.bind P (Predicate.single o f)"
ML {*
-let
- fun yield (@{code Predicate.Seq} f) = @{code next} yield (f ())
-in
- yield @{code "\<bottom> :: 'a Predicate.pred"} (*replace bottom with sequence to evaluate*)
-end
+structure Predicate =
+struct
+
+open Predicate;
+
+val pred_ref = ref (NONE : (unit -> term Predicate.pred) option);
+
+fun eval_pred thy t =
+ t
+ |> Eval.mk_term_of (fastype_of t)
+ |> (fn t => Code_ML.eval NONE ("Predicate.pred_ref", pred_ref) @{code pred_map} thy t []);
+
+fun eval_pred_elems thy t T length =
+ t |> eval_pred thy |> yieldn length |> fst |> HOLogic.mk_list T;
+
+fun analyze_compr thy t =
+ let
+ val split = case t of (Const (@{const_name Collect}, _) $ t') => t'
+ | _ => error ("Not a set comprehension: " ^ Syntax.string_of_term_global thy t);
+ val (body, Ts, fp) = HOLogic.strip_split split;
+ val (t_pred, args) = strip_comb body;
+ val pred = case t_pred of Const (pred, _) => pred
+ | _ => error ("Not a constant: " ^ Syntax.string_of_term_global thy t_pred);
+ val mode = map is_Bound args; (*FIXME what about higher-order modes?*)
+ val args' = filter_out is_Bound args;
+ val T = HOLogic.mk_tupleT fp Ts;
+ val mk = HOLogic.mk_tuple' fp T;
+ in (((pred, mode), args), (mk, T)) end;
+
+end;
*}
-fun anamorph :: "('b \<Rightarrow> ('a \<times> 'b) option) \<Rightarrow> index \<Rightarrow> 'b \<Rightarrow> 'a list \<times> 'b" where
- "anamorph f k x = (if k = 0 then ([], x)
- else case f x of None \<Rightarrow> ([], x) | Some (v, y) \<Rightarrow> let (vs, z) = anamorph f (k - 1) y in (v # vs, z))"
+
+text {* Example(s) *}
+
+inductive even :: "nat \<Rightarrow> bool" and odd :: "nat \<Rightarrow> bool" where
+ "even 0"
+ | "even n \<Longrightarrow> odd (Suc n)"
+ | "odd n \<Longrightarrow> even (Suc n)"
+
+setup {* pred_compile "even" *}
+thm even_codegen
+
+
+inductive append :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool" where
+ append_Nil: "append [] xs xs"
+ | append_Cons: "append xs ys zs \<Longrightarrow> append (x # xs) ys (x # zs)"
-ML {*
-let
- fun yield (@{code Predicate.Seq} f) = @{code next} yield (f ())
- fun yieldn k = @{code anamorph} yield k
-in
- yieldn 0 (*replace with number of elements to retrieve*)
- @{code "\<bottom> :: 'a Predicate.pred"} (*replace bottom with sequence to evaluate*)
-end
-*}
+setup {* pred_compile "append" *}
+thm append_codegen
+
+
+inductive partition :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool"
+ for f where
+ "partition f [] [] []"
+ | "f x \<Longrightarrow> partition f xs ys zs \<Longrightarrow> partition f (x # xs) (x # ys) zs"
+ | "\<not> f x \<Longrightarrow> partition f xs ys zs \<Longrightarrow> partition f (x # xs) ys (x # zs)"
+
+setup {* pred_compile "partition" *}
+thm partition_codegen
+
+setup {* pred_compile "tranclp" *}
+thm tranclp_codegen
+
+ML_val {* Predicate_Compile.modes_of @{theory} @{const_name partition} *}
+ML_val {* Predicate_Compile.modes_of @{theory} @{const_name tranclp} *}
+
+ML_val {* Predicate.analyze_compr @{theory} @{term "{n. odd n}"} *}
section {* Example for user interface *}
--- a/src/HOL/ex/Quickcheck_Generators.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ex/Quickcheck_Generators.thy Mon May 11 17:20:52 2009 +0200
@@ -6,62 +6,6 @@
imports Quickcheck State_Monad
begin
-subsection {* Type @{typ "'a \<Rightarrow> 'b"} *}
-
-ML {*
-structure Random_Engine =
-struct
-
-open Random_Engine;
-
-fun random_fun (T1 : typ) (T2 : typ) (eq : 'a -> 'a -> bool) (term_of : 'a -> term)
- (random : Random_Engine.seed -> ('b * (unit -> term)) * Random_Engine.seed)
- (random_split : Random_Engine.seed -> Random_Engine.seed * Random_Engine.seed)
- (seed : Random_Engine.seed) =
- let
- val (seed', seed'') = random_split seed;
- val state = ref (seed', [], Const (@{const_name undefined}, T1 --> T2));
- val fun_upd = Const (@{const_name fun_upd},
- (T1 --> T2) --> T1 --> T2 --> T1 --> T2);
- fun random_fun' x =
- let
- val (seed, fun_map, f_t) = ! state;
- in case AList.lookup (uncurry eq) fun_map x
- of SOME y => y
- | NONE => let
- val t1 = term_of x;
- val ((y, t2), seed') = random seed;
- val fun_map' = (x, y) :: fun_map;
- val f_t' = fun_upd $ f_t $ t1 $ t2 ();
- val _ = state := (seed', fun_map', f_t');
- in y end
- end;
- fun term_fun' () = #3 (! state);
- in ((random_fun', term_fun'), seed'') end;
-
-end
-*}
-
-axiomatization
- random_fun_aux :: "typerep \<Rightarrow> typerep \<Rightarrow> ('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> term)
- \<Rightarrow> (seed \<Rightarrow> ('b \<times> (unit \<Rightarrow> term)) \<times> seed) \<Rightarrow> (seed \<Rightarrow> seed \<times> seed)
- \<Rightarrow> seed \<Rightarrow> (('a \<Rightarrow> 'b) \<times> (unit \<Rightarrow> term)) \<times> seed"
-
-code_const random_fun_aux (SML "Random'_Engine.random'_fun")
-
-instantiation "fun" :: ("{eq, term_of}", "{type, random}") random
-begin
-
-definition random_fun :: "index \<Rightarrow> seed \<Rightarrow> (('a \<Rightarrow> 'b) \<times> (unit \<Rightarrow> term)) \<times> seed" where
- "random n = random_fun_aux TYPEREP('a) TYPEREP('b) (op =) Code_Eval.term_of (random n) split_seed"
-
-instance ..
-
-end
-
-code_reserved SML Random_Engine
-
-
subsection {* Datatypes *}
definition
--- a/src/HOL/ex/ReflectionEx.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ex/ReflectionEx.thy Mon May 11 17:20:52 2009 +0200
@@ -385,7 +385,7 @@
(* An example for equations containing type variables *)
datatype prod = Zero | One | Var nat | Mul prod prod
| Pw prod nat | PNM nat nat prod
-consts Iprod :: " prod \<Rightarrow> ('a::{ordered_idom,recpower}) list \<Rightarrow>'a"
+consts Iprod :: " prod \<Rightarrow> ('a::{ordered_idom}) list \<Rightarrow>'a"
primrec
"Iprod Zero vs = 0"
"Iprod One vs = 1"
@@ -397,7 +397,7 @@
datatype sgn = Pos prod | Neg prod | ZeroEq prod | NZeroEq prod | Tr | F
| Or sgn sgn | And sgn sgn
-consts Isgn :: " sgn \<Rightarrow> ('a::{ordered_idom, recpower}) list \<Rightarrow>bool"
+consts Isgn :: " sgn \<Rightarrow> ('a::{ordered_idom}) list \<Rightarrow>bool"
primrec
"Isgn Tr vs = True"
"Isgn F vs = False"
@@ -410,7 +410,7 @@
lemmas eqs = Isgn.simps Iprod.simps
-lemma "(x::'a::{ordered_idom, recpower})^4 * y * z * y^2 * z^23 > 0"
+lemma "(x::'a::{ordered_idom})^4 * y * z * y^2 * z^23 > 0"
apply (reify eqs)
oops
--- a/src/HOL/ex/predicate_compile.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOL/ex/predicate_compile.ML Mon May 11 17:20:52 2009 +0200
@@ -6,13 +6,17 @@
signature PREDICATE_COMPILE =
sig
- val create_def_equation': string -> (int list option list * int list) option -> theory -> theory
+ type mode = int list option list * int list
+ val create_def_equation': string -> mode option -> theory -> theory
val create_def_equation: string -> theory -> theory
- val intro_rule: theory -> string -> (int list option list * int list) -> thm
- val elim_rule: theory -> string -> (int list option list * int list) -> thm
+ val intro_rule: theory -> string -> mode -> thm
+ val elim_rule: theory -> string -> mode -> thm
val strip_intro_concl : term -> int -> (term * (term list * term list))
val code_ind_intros_attrib : attribute
val code_ind_cases_attrib : attribute
+ val print_alternative_rules : theory -> theory
+ val modename_of: theory -> string -> mode -> string
+ val modes_of: theory -> string -> mode list
val setup : theory -> theory
val code_pred : string -> Proof.context -> Proof.state
val code_pred_cmd : string -> Proof.context -> Proof.state
@@ -25,23 +29,101 @@
structure Predicate_Compile: PREDICATE_COMPILE =
struct
+(** auxiliary **)
+
+(* debug stuff *)
+
+fun tracing s = (if ! Toplevel.debug then Output.tracing s else ());
+
+fun print_tac s = (if ! Toplevel.debug then Tactical.print_tac s else Seq.single);
+fun debug_tac msg = (fn st => (tracing msg; Seq.single st));
+
+val do_proofs = ref true;
+
+
+(** fundamentals **)
+
+(* syntactic operations *)
+
+fun mk_eq (x, xs) =
+ let fun mk_eqs _ [] = []
+ | mk_eqs a (b::cs) =
+ HOLogic.mk_eq (Free (a, fastype_of b), b) :: mk_eqs a cs
+ in mk_eqs x xs end;
+
+fun mk_tupleT [] = HOLogic.unitT
+ | mk_tupleT Ts = foldr1 HOLogic.mk_prodT Ts;
+
+fun mk_tuple [] = HOLogic.unit
+ | mk_tuple ts = foldr1 HOLogic.mk_prod ts;
+
+fun dest_tuple (Const (@{const_name Product_Type.Unity}, _)) = []
+ | dest_tuple (Const (@{const_name Pair}, _) $ t1 $ t2) = t1 :: (dest_tuple t2)
+ | dest_tuple t = [t]
+
+fun mk_pred_enumT T = Type ("Predicate.pred", [T])
+
+fun dest_pred_enumT (Type ("Predicate.pred", [T])) = T
+ | dest_pred_enumT T = raise TYPE ("dest_pred_enumT", [T], []);
+
+fun mk_Enum f =
+ let val T as Type ("fun", [T', _]) = fastype_of f
+ in
+ Const (@{const_name Predicate.Pred}, T --> mk_pred_enumT T') $ f
+ end;
+
+fun mk_Eval (f, x) =
+ let val T = fastype_of x
+ in
+ Const (@{const_name Predicate.eval}, mk_pred_enumT T --> T --> HOLogic.boolT) $ f $ x
+ end;
+
+fun mk_empty T = Const (@{const_name Orderings.bot}, mk_pred_enumT T);
+
+fun mk_single t =
+ let val T = fastype_of t
+ in Const(@{const_name Predicate.single}, T --> mk_pred_enumT T) $ t end;
+
+fun mk_bind (x, f) =
+ let val T as Type ("fun", [_, U]) = fastype_of f
+ in
+ Const (@{const_name Predicate.bind}, fastype_of x --> T --> U) $ x $ f
+ end;
+
+val mk_sup = HOLogic.mk_binop @{const_name sup};
+
+fun mk_if_predenum cond = Const (@{const_name Predicate.if_pred},
+ HOLogic.boolT --> mk_pred_enumT HOLogic.unitT) $ cond;
+
+fun mk_not_pred t = let val T = mk_pred_enumT HOLogic.unitT
+ in Const (@{const_name Predicate.not_pred}, T --> T) $ t end
+
+
+(* data structures *)
+
+type mode = int list option list * int list;
+
+val mode_ord = prod_ord (list_ord (option_ord (list_ord int_ord))) (list_ord int_ord);
+
structure PredModetab = TableFun(
- type key = (string * (int list option list * int list))
- val ord = prod_ord fast_string_ord (prod_ord
- (list_ord (option_ord (list_ord int_ord))) (list_ord int_ord)))
+ type key = string * mode
+ val ord = prod_ord fast_string_ord mode_ord
+);
+(*FIXME scrap boilerplate*)
+
structure IndCodegenData = TheoryDataFun
(
type T = {names : string PredModetab.table,
- modes : ((int list option list * int list) list) Symtab.table,
+ modes : mode list Symtab.table,
function_defs : Thm.thm Symtab.table,
function_intros : Thm.thm Symtab.table,
function_elims : Thm.thm Symtab.table,
- intro_rules : (Thm.thm list) Symtab.table,
+ intro_rules : Thm.thm list Symtab.table,
elim_rules : Thm.thm Symtab.table,
nparams : int Symtab.table
- };
+ }; (*FIXME: better group tables according to key*)
(* names: map from inductive predicate and mode to function name (string).
modes: map from inductive predicates to modes
function_defs: map from function name to definition
@@ -119,26 +201,12 @@
intro_rules = #intro_rules x, elim_rules = #elim_rules x,
nparams = f (#nparams x)}) thy
-(* Debug stuff and tactics ***********************************************************)
-
-fun tracing s = (if ! Toplevel.debug then Output.tracing s else ());
-fun print_tac s = (if ! Toplevel.debug then Tactical.print_tac s else Seq.single);
-
-fun debug_tac msg = (fn st =>
- (tracing msg; Seq.single st));
-
(* removes first subgoal *)
fun mycheat_tac thy i st =
(Tactic.rtac (SkipProof.make_thm thy (Var (("A", 0), propT))) i) st
-val (do_proofs : bool ref) = ref true;
-
(* Lightweight mode analysis **********************************************)
-(* Hack for message from old code generator *)
-val message = tracing;
-
-
(**************************************************************************)
(* source code from old code generator ************************************)
@@ -157,7 +225,8 @@
| _ => false)
in check end;
-(**** check if a type is an equality type (i.e. doesn't contain fun) ****)
+(**** check if a type is an equality type (i.e. doesn't contain fun)
+ FIXME this is only an approximation ****)
fun is_eqT (Type (s, Ts)) = s <> "fun" andalso forall is_eqT Ts
| is_eqT _ = true;
@@ -169,7 +238,7 @@
| SOME js => enclose "[" "]" (commas (map string_of_int js)))
(iss @ [SOME is]));
-fun print_modes modes = message ("Inferred modes:\n" ^
+fun print_modes modes = tracing ("Inferred modes:\n" ^
cat_lines (map (fn (s, ms) => s ^ ": " ^ commas (map
string_of_mode ms)) modes));
@@ -186,6 +255,7 @@
(get_args' is (i+1) ts)
in get_args' is 1 ts end
+(*FIXME this function should not be named merge... make it local instead*)
fun merge xs [] = xs
| merge [] ys = ys
| merge (x::xs) (y::ys) = if length x >= length y then x::merge xs (y::ys)
@@ -201,7 +271,8 @@
fun cprods xss = foldr (map op :: o cprod) [[]] xss;
-datatype mode = Mode of (int list option list * int list) * int list * mode option list;
+datatype hmode = Mode of mode * int list * hmode option list; (*FIXME don't understand
+ why there is another mode type!?*)
fun modes_of modes t =
let
@@ -289,11 +360,11 @@
in (p, List.filter (fn m => case find_index
(not o check_mode_clause thy param_vs modes m) rs of
~1 => true
- | i => (message ("Clause " ^ string_of_int (i+1) ^ " of " ^
+ | i => (tracing ("Clause " ^ string_of_int (i+1) ^ " of " ^
p ^ " violates mode " ^ string_of_mode m); false)) ms)
end;
-fun fixp f (x : (string * (int list option list * int list) list) list) =
+fun fixp f (x : (string * mode list) list) =
let val y = f x
in if x = y then x else fixp f y end;
@@ -310,66 +381,6 @@
(*****************************************************************************************)
(**** term construction ****)
-fun mk_eq (x, xs) =
- let fun mk_eqs _ [] = []
- | mk_eqs a (b::cs) =
- HOLogic.mk_eq (Free (a, fastype_of b), b) :: mk_eqs a cs
- in mk_eqs x xs end;
-
-fun mk_tuple [] = HOLogic.unit
- | mk_tuple ts = foldr1 HOLogic.mk_prod ts;
-
-fun dest_tuple (Const (@{const_name Product_Type.Unity}, _)) = []
- | dest_tuple (Const (@{const_name Pair}, _) $ t1 $ t2) = t1 :: (dest_tuple t2)
- | dest_tuple t = [t]
-
-fun mk_tupleT [] = HOLogic.unitT
- | mk_tupleT Ts = foldr1 HOLogic.mk_prodT Ts;
-
-fun mk_pred_enumT T = Type ("Predicate.pred", [T])
-
-fun dest_pred_enumT (Type ("Predicate.pred", [T])) = T
- | dest_pred_enumT T = raise TYPE ("dest_pred_enumT", [T], []);
-
-fun mk_single t =
- let val T = fastype_of t
- in Const(@{const_name Predicate.single}, T --> mk_pred_enumT T) $ t end;
-
-fun mk_empty T = Const (@{const_name Orderings.bot}, mk_pred_enumT T);
-
-fun mk_if_predenum cond = Const (@{const_name Predicate.if_pred},
- HOLogic.boolT --> mk_pred_enumT HOLogic.unitT)
- $ cond
-
-fun mk_not_pred t = let val T = mk_pred_enumT HOLogic.unitT
- in Const (@{const_name Predicate.not_pred}, T --> T) $ t end
-
-fun mk_bind (x, f) =
- let val T as Type ("fun", [_, U]) = fastype_of f
- in
- Const (@{const_name Predicate.bind}, fastype_of x --> T --> U) $ x $ f
- end;
-
-fun mk_Enum f =
- let val T as Type ("fun", [T', _]) = fastype_of f
- in
- Const (@{const_name Predicate.Pred}, T --> mk_pred_enumT T') $ f
- end;
-
-fun mk_Eval (f, x) =
- let val T = fastype_of x
- in
- Const (@{const_name Predicate.eval}, mk_pred_enumT T --> T --> HOLogic.boolT) $ f $ x
- end;
-
-fun mk_Eval' f =
- let val T = fastype_of f
- in
- Const (@{const_name Predicate.eval}, T --> dest_pred_enumT T --> HOLogic.boolT) $ f
- end;
-
-val mk_sup = HOLogic.mk_binop @{const_name sup};
-
(* for simple modes (e.g. parameters) only: better call it param_funT *)
(* or even better: remove it and only use funT'_of - some modifications to funT'_of necessary *)
fun funT_of T NONE = T
@@ -428,13 +439,16 @@
(v', mk_empty U')]))
end;
-fun modename thy name mode = let
+fun modename_of thy name mode = let
val v = (PredModetab.lookup (#names (IndCodegenData.get thy)) (name, mode))
- in if (is_some v) then the v
- else error ("fun modename - definition not found: name: " ^ name ^ " mode: " ^ (makestring mode))
+ in if (is_some v) then the v (*FIXME use case here*)
+ else error ("fun modename_of - definition not found: name: " ^ name ^ " mode: " ^ (makestring mode))
end
-(* function can be removed *)
+fun modes_of thy =
+ these o Symtab.lookup ((#modes o IndCodegenData.get) thy);
+
+(*FIXME function can be removed*)
fun mk_funcomp f t =
let
val names = Term.add_free_names t [];
@@ -453,7 +467,7 @@
val f' = case f of
Const (name, T) =>
if AList.defined op = modes name then
- Const (modename thy name (iss, is'), funT'_of (iss, is') T)
+ Const (modename_of thy name (iss, is'), funT'_of (iss, is') T)
else error "compile param: Not an inductive predicate with correct mode"
| Free (name, T) => Free (name, funT_of T (SOME is'))
in list_comb (f', params' @ args') end
@@ -467,7 +481,7 @@
val (Ts, Us) = get_args is
(curry Library.drop (length ms) (fst (strip_type T)))
val params' = map (compile_param thy modes) (ms ~~ params)
- val mode_id = modename thy name mode
+ val mode_id = modename_of thy name mode
in list_comb (Const (mode_id, ((map fastype_of params') @ Ts) --->
mk_pred_enumT (mk_tupleT Us)), params')
end
@@ -560,7 +574,7 @@
val cl_ts =
map (fn cl => compile_clause thy
all_vs param_vs modes mode cl (mk_tuple xs)) cls;
- val mode_id = modename thy s mode
+ val mode_id = modename_of thy s mode
in
HOLogic.mk_Trueprop (HOLogic.mk_eq
(list_comb (Const (mode_id, (Ts1' @ Us1) --->
@@ -595,7 +609,7 @@
fold Term.add_consts intrs [] |> map fst
|> filter_out (member (op =) preds) |> filter (is_ind_pred thy)
-fun print_arities arities = message ("Arities:\n" ^
+fun print_arities arities = tracing ("Arities:\n" ^
cat_lines (map (fn (s, (ks, k)) => s ^ ": " ^
space_implode " -> " (map
(fn NONE => "X" | SOME k' => string_of_int k')
@@ -695,10 +709,10 @@
(* Proving equivalence of term *)
-fun intro_rule thy pred mode = modename thy pred mode
+fun intro_rule thy pred mode = modename_of thy pred mode
|> Symtab.lookup (#function_intros (IndCodegenData.get thy)) |> the
-fun elim_rule thy pred mode = modename thy pred mode
+fun elim_rule thy pred mode = modename_of thy pred mode
|> Symtab.lookup (#function_elims (IndCodegenData.get thy)) |> the
fun pred_intros thy predname = let
@@ -715,7 +729,7 @@
end
fun function_definition thy pred mode =
- modename thy pred mode |> Symtab.lookup (#function_defs (IndCodegenData.get thy)) |> the
+ modename_of thy pred mode |> Symtab.lookup (#function_defs (IndCodegenData.get thy)) |> the
fun is_Type (Type _) = true
| is_Type _ = false
@@ -977,7 +991,7 @@
in nth (#elims (snd ind_result)) index end)
fun prove_one_direction thy all_vs param_vs modes clauses ((pred, T), mode) = let
- val elim_rule = the (Symtab.lookup (#function_elims (IndCodegenData.get thy)) (modename thy pred mode))
+ val elim_rule = the (Symtab.lookup (#function_elims (IndCodegenData.get thy)) (modename_of thy pred mode))
(* val ind_result = InductivePackage.the_inductive (ProofContext.init thy) pred
val index = find_index (fn s => s = pred) (#names (fst ind_result))
val (_, T) = dest_Const (nth (#preds (snd ind_result)) index) *)
@@ -1229,7 +1243,7 @@
(* main function *********************************************************************)
(*************************************************************************************)
-fun create_def_equation' ind_name (mode : (int list option list * int list) option) thy =
+fun create_def_equation' ind_name (mode : mode option) thy =
let
val _ = tracing ("starting create_def_equation' with " ^ ind_name)
val (prednames, preds) =
@@ -1253,6 +1267,7 @@
val _ = tracing ("calling preds: " ^ makestring name_of_calls)
val _ = tracing "starting recursive compilations"
fun rec_call name thy =
+ (*FIXME use member instead of infix mem*)
if not (name mem (Symtab.keys (#modes (IndCodegenData.get thy)))) then
create_def_equation name thy else thy
val thy'' = fold rec_call name_of_calls thy'
--- a/src/HOLCF/Adm.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Adm.thy Mon May 11 17:20:52 2009 +0200
@@ -78,7 +78,7 @@
"\<lbrakk>chain (Y::nat \<Rightarrow> 'a::cpo); \<forall>i. \<exists>j\<ge>i. P (Y j)\<rbrakk> \<Longrightarrow>
(\<Squnion>i. Y i) = (\<Squnion>i. Y (LEAST j. i \<le> j \<and> P (Y j)))"
apply (frule (1) adm_disj_lemma1)
- apply (rule antisym_less)
+ apply (rule below_antisym)
apply (rule lub_mono, assumption+)
apply (erule chain_mono)
apply (simp add: adm_disj_lemma2)
@@ -122,7 +122,7 @@
text {* admissibility and continuity *}
-lemma adm_less: "\<lbrakk>cont u; cont v\<rbrakk> \<Longrightarrow> adm (\<lambda>x. u x \<sqsubseteq> v x)"
+lemma adm_below: "\<lbrakk>cont u; cont v\<rbrakk> \<Longrightarrow> adm (\<lambda>x. u x \<sqsubseteq> v x)"
apply (rule admI)
apply (simp add: cont2contlubE)
apply (rule lub_mono)
@@ -132,7 +132,7 @@
done
lemma adm_eq: "\<lbrakk>cont u; cont v\<rbrakk> \<Longrightarrow> adm (\<lambda>x. u x = v x)"
-by (simp add: po_eq_conv adm_conj adm_less)
+by (simp add: po_eq_conv adm_conj adm_below)
lemma adm_subst: "\<lbrakk>cont t; adm P\<rbrakk> \<Longrightarrow> adm (\<lambda>x. P (t x))"
apply (rule admI)
@@ -142,11 +142,11 @@
apply (erule spec)
done
-lemma adm_not_less: "cont t \<Longrightarrow> adm (\<lambda>x. \<not> t x \<sqsubseteq> u)"
+lemma adm_not_below: "cont t \<Longrightarrow> adm (\<lambda>x. \<not> t x \<sqsubseteq> u)"
apply (rule admI)
apply (drule_tac x=0 in spec)
apply (erule contrapos_nn)
-apply (erule rev_trans_less)
+apply (erule rev_below_trans)
apply (erule cont2mono [THEN monofunE])
apply (erule is_ub_thelub)
done
@@ -179,21 +179,21 @@
apply (drule (1) compactD2, simp)
apply (erule exE, rule_tac x=i in exI)
apply (rule max_in_chainI)
-apply (rule antisym_less)
+apply (rule below_antisym)
apply (erule (1) chain_mono)
-apply (erule (1) trans_less [OF is_ub_thelub])
+apply (erule (1) below_trans [OF is_ub_thelub])
done
text {* admissibility and compactness *}
-lemma adm_compact_not_less: "\<lbrakk>compact k; cont t\<rbrakk> \<Longrightarrow> adm (\<lambda>x. \<not> k \<sqsubseteq> t x)"
+lemma adm_compact_not_below: "\<lbrakk>compact k; cont t\<rbrakk> \<Longrightarrow> adm (\<lambda>x. \<not> k \<sqsubseteq> t x)"
unfolding compact_def by (rule adm_subst)
lemma adm_neq_compact: "\<lbrakk>compact k; cont t\<rbrakk> \<Longrightarrow> adm (\<lambda>x. t x \<noteq> k)"
-by (simp add: po_eq_conv adm_imp adm_not_less adm_compact_not_less)
+by (simp add: po_eq_conv adm_imp adm_not_below adm_compact_not_below)
lemma adm_compact_neq: "\<lbrakk>compact k; cont t\<rbrakk> \<Longrightarrow> adm (\<lambda>x. k \<noteq> t x)"
-by (simp add: po_eq_conv adm_imp adm_not_less adm_compact_not_less)
+by (simp add: po_eq_conv adm_imp adm_not_below adm_compact_not_below)
lemma compact_UU [simp, intro]: "compact \<bottom>"
by (rule compactI, simp add: adm_not_free)
@@ -210,7 +210,7 @@
lemmas adm_lemmas [simp] =
adm_not_free adm_conj adm_all adm_ball adm_disj adm_imp adm_iff
- adm_less adm_eq adm_not_less
- adm_compact_not_less adm_compact_neq adm_neq_compact adm_not_UU
+ adm_below adm_eq adm_not_below
+ adm_compact_not_below adm_compact_neq adm_neq_compact adm_not_UU
end
--- a/src/HOLCF/Algebraic.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Algebraic.thy Mon May 11 17:20:52 2009 +0200
@@ -33,21 +33,21 @@
locale pre_deflation =
fixes f :: "'a \<rightarrow> 'a::cpo"
- assumes less: "\<And>x. f\<cdot>x \<sqsubseteq> x"
+ assumes below: "\<And>x. f\<cdot>x \<sqsubseteq> x"
assumes finite_range: "finite (range (\<lambda>x. f\<cdot>x))"
begin
-lemma iterate_less: "iterate i\<cdot>f\<cdot>x \<sqsubseteq> x"
-by (induct i, simp_all add: trans_less [OF less])
+lemma iterate_below: "iterate i\<cdot>f\<cdot>x \<sqsubseteq> x"
+by (induct i, simp_all add: below_trans [OF below])
lemma iterate_fixed: "f\<cdot>x = x \<Longrightarrow> iterate i\<cdot>f\<cdot>x = x"
by (induct i, simp_all)
lemma antichain_iterate_app: "i \<le> j \<Longrightarrow> iterate j\<cdot>f\<cdot>x \<sqsubseteq> iterate i\<cdot>f\<cdot>x"
apply (erule le_Suc_induct)
-apply (simp add: less)
-apply (rule refl_less)
-apply (erule (1) trans_less)
+apply (simp add: below)
+apply (rule below_refl)
+apply (erule (1) below_trans)
done
lemma finite_range_iterate_app: "finite (range (\<lambda>i. iterate i\<cdot>f\<cdot>x))"
@@ -144,7 +144,7 @@
next
fix x :: 'a
show "d\<cdot>x \<sqsubseteq> x"
- by (rule MOST_d, simp add: iterate_less)
+ by (rule MOST_d, simp add: iterate_below)
next
from finite_range
have "finite {x. f\<cdot>x = x}"
@@ -163,7 +163,7 @@
interpret d: finite_deflation d by fact
fix x
show "\<And>x. (d oo f)\<cdot>x \<sqsubseteq> x"
- by (simp, rule trans_less [OF d.less f])
+ by (simp, rule below_trans [OF d.below f])
show "finite (range (\<lambda>x. (d oo f)\<cdot>x))"
by (rule finite_subset [OF _ d.finite_range], auto)
qed
@@ -185,9 +185,9 @@
apply safe
apply (erule subst)
apply (rule d.idem)
- apply (rule antisym_less)
+ apply (rule below_antisym)
apply (rule f)
- apply (erule subst, rule d.less)
+ apply (erule subst, rule d.below)
apply simp
done
qed
@@ -199,18 +199,17 @@
typedef (open) 'a fin_defl = "{d::'a \<rightarrow> 'a. finite_deflation d}"
by (fast intro: finite_deflation_approx)
-instantiation fin_defl :: (profinite) sq_ord
+instantiation fin_defl :: (profinite) below
begin
-definition
- sq_le_fin_defl_def:
+definition below_fin_defl_def:
"op \<sqsubseteq> \<equiv> \<lambda>x y. Rep_fin_defl x \<sqsubseteq> Rep_fin_defl y"
instance ..
end
instance fin_defl :: (profinite) po
-by (rule typedef_po [OF type_definition_fin_defl sq_le_fin_defl_def])
+by (rule typedef_po [OF type_definition_fin_defl below_fin_defl_def])
lemma finite_deflation_Rep_fin_defl: "finite_deflation (Rep_fin_defl d)"
using Rep_fin_defl by simp
@@ -218,27 +217,27 @@
interpretation Rep_fin_defl: finite_deflation "Rep_fin_defl d"
by (rule finite_deflation_Rep_fin_defl)
-lemma fin_defl_lessI:
+lemma fin_defl_belowI:
"(\<And>x. Rep_fin_defl a\<cdot>x = x \<Longrightarrow> Rep_fin_defl b\<cdot>x = x) \<Longrightarrow> a \<sqsubseteq> b"
-unfolding sq_le_fin_defl_def
-by (rule Rep_fin_defl.lessI)
+unfolding below_fin_defl_def
+by (rule Rep_fin_defl.belowI)
-lemma fin_defl_lessD:
+lemma fin_defl_belowD:
"\<lbrakk>a \<sqsubseteq> b; Rep_fin_defl a\<cdot>x = x\<rbrakk> \<Longrightarrow> Rep_fin_defl b\<cdot>x = x"
-unfolding sq_le_fin_defl_def
-by (rule Rep_fin_defl.lessD)
+unfolding below_fin_defl_def
+by (rule Rep_fin_defl.belowD)
lemma fin_defl_eqI:
"(\<And>x. Rep_fin_defl a\<cdot>x = x \<longleftrightarrow> Rep_fin_defl b\<cdot>x = x) \<Longrightarrow> a = b"
-apply (rule antisym_less)
-apply (rule fin_defl_lessI, simp)
-apply (rule fin_defl_lessI, simp)
+apply (rule below_antisym)
+apply (rule fin_defl_belowI, simp)
+apply (rule fin_defl_belowI, simp)
done
lemma Abs_fin_defl_mono:
"\<lbrakk>finite_deflation a; finite_deflation b; a \<sqsubseteq> b\<rbrakk>
\<Longrightarrow> Abs_fin_defl a \<sqsubseteq> Abs_fin_defl b"
-unfolding sq_le_fin_defl_def
+unfolding below_fin_defl_def
by (simp add: Abs_fin_defl_inverse)
@@ -257,7 +256,7 @@
apply (rule pre_deflation.finite_deflation_d)
apply (rule pre_deflation_d_f)
apply (rule finite_deflation_approx)
-apply (rule Rep_fin_defl.less)
+apply (rule Rep_fin_defl.below)
done
lemma fd_take_fixed_iff:
@@ -265,10 +264,10 @@
approx i\<cdot>x = x \<and> Rep_fin_defl d\<cdot>x = x"
unfolding Rep_fin_defl_fd_take
by (rule eventual_iterate_oo_fixed_iff
- [OF finite_deflation_approx Rep_fin_defl.less])
+ [OF finite_deflation_approx Rep_fin_defl.below])
-lemma fd_take_less: "fd_take n d \<sqsubseteq> d"
-apply (rule fin_defl_lessI)
+lemma fd_take_below: "fd_take n d \<sqsubseteq> d"
+apply (rule fin_defl_belowI)
apply (simp add: fd_take_fixed_iff)
done
@@ -278,16 +277,16 @@
done
lemma fd_take_mono: "a \<sqsubseteq> b \<Longrightarrow> fd_take n a \<sqsubseteq> fd_take n b"
-apply (rule fin_defl_lessI)
+apply (rule fin_defl_belowI)
apply (simp add: fd_take_fixed_iff)
-apply (simp add: fin_defl_lessD)
+apply (simp add: fin_defl_belowD)
done
lemma approx_fixed_le_lemma: "\<lbrakk>i \<le> j; approx i\<cdot>x = x\<rbrakk> \<Longrightarrow> approx j\<cdot>x = x"
by (erule subst, simp add: min_def)
lemma fd_take_chain: "m \<le> n \<Longrightarrow> fd_take m a \<sqsubseteq> fd_take n a"
-apply (rule fin_defl_lessI)
+apply (rule fin_defl_belowI)
apply (simp add: fd_take_fixed_iff)
apply (simp add: approx_fixed_le_lemma)
done
@@ -304,9 +303,9 @@
lemma fd_take_covers: "\<exists>n. fd_take n a = a"
apply (rule_tac x=
"Max ((\<lambda>x. LEAST n. approx n\<cdot>x = x) ` {x. Rep_fin_defl a\<cdot>x = x})" in exI)
-apply (rule antisym_less)
-apply (rule fd_take_less)
-apply (rule fin_defl_lessI)
+apply (rule below_antisym)
+apply (rule fd_take_below)
+apply (rule fin_defl_belowI)
apply (simp add: fd_take_fixed_iff)
apply (rule approx_fixed_le_lemma)
apply (rule Max_ge)
@@ -320,9 +319,9 @@
apply (rule Rep_fin_defl.compact)
done
-interpretation fin_defl: basis_take sq_le fd_take
+interpretation fin_defl: basis_take below fd_take
apply default
-apply (rule fd_take_less)
+apply (rule fd_take_below)
apply (rule fd_take_idem)
apply (erule fd_take_mono)
apply (rule fd_take_chain, simp)
@@ -333,10 +332,10 @@
subsection {* Defining algebraic deflations by ideal completion *}
typedef (open) 'a alg_defl =
- "{S::'a fin_defl set. sq_le.ideal S}"
-by (fast intro: sq_le.ideal_principal)
+ "{S::'a fin_defl set. below.ideal S}"
+by (fast intro: below.ideal_principal)
-instantiation alg_defl :: (profinite) sq_ord
+instantiation alg_defl :: (profinite) below
begin
definition
@@ -346,19 +345,19 @@
end
instance alg_defl :: (profinite) po
-by (rule sq_le.typedef_ideal_po
- [OF type_definition_alg_defl sq_le_alg_defl_def])
+by (rule below.typedef_ideal_po
+ [OF type_definition_alg_defl below_alg_defl_def])
instance alg_defl :: (profinite) cpo
-by (rule sq_le.typedef_ideal_cpo
- [OF type_definition_alg_defl sq_le_alg_defl_def])
+by (rule below.typedef_ideal_cpo
+ [OF type_definition_alg_defl below_alg_defl_def])
lemma Rep_alg_defl_lub:
"chain Y \<Longrightarrow> Rep_alg_defl (\<Squnion>i. Y i) = (\<Union>i. Rep_alg_defl (Y i))"
-by (rule sq_le.typedef_ideal_rep_contlub
- [OF type_definition_alg_defl sq_le_alg_defl_def])
+by (rule below.typedef_ideal_rep_contlub
+ [OF type_definition_alg_defl below_alg_defl_def])
-lemma ideal_Rep_alg_defl: "sq_le.ideal (Rep_alg_defl xs)"
+lemma ideal_Rep_alg_defl: "below.ideal (Rep_alg_defl xs)"
by (rule Rep_alg_defl [unfolded mem_Collect_eq])
definition
@@ -368,15 +367,15 @@
lemma Rep_alg_defl_principal:
"Rep_alg_defl (alg_defl_principal t) = {u. u \<sqsubseteq> t}"
unfolding alg_defl_principal_def
-by (simp add: Abs_alg_defl_inverse sq_le.ideal_principal)
+by (simp add: Abs_alg_defl_inverse below.ideal_principal)
interpretation alg_defl:
- ideal_completion sq_le fd_take alg_defl_principal Rep_alg_defl
+ ideal_completion below fd_take alg_defl_principal Rep_alg_defl
apply default
apply (rule ideal_Rep_alg_defl)
apply (erule Rep_alg_defl_lub)
apply (rule Rep_alg_defl_principal)
-apply (simp only: sq_le_alg_defl_def)
+apply (simp only: below_alg_defl_def)
done
text {* Algebraic deflations are pointed *}
@@ -443,7 +442,7 @@
"cast\<cdot>(alg_defl_principal a) = Rep_fin_defl a"
unfolding cast_def
apply (rule alg_defl.basis_fun_principal)
-apply (simp only: sq_le_fin_defl_def)
+apply (simp only: below_fin_defl_def)
done
lemma deflation_cast: "deflation (cast\<cdot>d)"
@@ -522,10 +521,10 @@
apply (rule finite_deflation_p_d_e)
apply (rule finite_deflation_cast)
apply (rule compact_approx)
- apply (rule sq_ord_less_eq_trans [OF _ d])
+ apply (rule below_eq_trans [OF _ d])
apply (rule monofun_cfun_fun)
apply (rule monofun_cfun_arg)
- apply (rule approx_less)
+ apply (rule approx_below)
done
show "(\<Squnion>i. ?a i) = ID"
apply (rule ext_cfun, simp)
--- a/src/HOLCF/Bifinite.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Bifinite.thy Mon May 11 17:20:52 2009 +0200
@@ -19,7 +19,7 @@
class bifinite = profinite + pcpo
-lemma approx_less: "approx i\<cdot>x \<sqsubseteq> x"
+lemma approx_below: "approx i\<cdot>x \<sqsubseteq> x"
proof -
have "chain (\<lambda>i. approx i\<cdot>x)" by simp
hence "approx i\<cdot>x \<sqsubseteq> (\<Squnion>i. approx i\<cdot>x)" by (rule is_ub_thelub)
@@ -32,7 +32,7 @@
show "approx i\<cdot>(approx i\<cdot>x) = approx i\<cdot>x"
by (rule approx_idem)
show "approx i\<cdot>x \<sqsubseteq> x"
- by (rule approx_less)
+ by (rule approx_below)
show "finite {x. approx i\<cdot>x = x}"
by (rule finite_fixes_approx)
qed
@@ -49,17 +49,17 @@
by (rule ext_cfun, simp add: contlub_cfun_fun)
lemma approx_strict [simp]: "approx i\<cdot>\<bottom> = \<bottom>"
-by (rule UU_I, rule approx_less)
+by (rule UU_I, rule approx_below)
lemma approx_approx1:
"i \<le> j \<Longrightarrow> approx i\<cdot>(approx j\<cdot>x) = approx i\<cdot>x"
-apply (rule deflation_less_comp1 [OF deflation_approx deflation_approx])
+apply (rule deflation_below_comp1 [OF deflation_approx deflation_approx])
apply (erule chain_mono [OF chain_approx])
done
lemma approx_approx2:
"j \<le> i \<Longrightarrow> approx i\<cdot>(approx j\<cdot>x) = approx j\<cdot>x"
-apply (rule deflation_less_comp2 [OF deflation_approx deflation_approx])
+apply (rule deflation_below_comp2 [OF deflation_approx deflation_approx])
apply (erule chain_mono [OF chain_approx])
done
@@ -99,7 +99,7 @@
thus "P x" by simp
qed
-lemma profinite_less_ext: "(\<And>i. approx i\<cdot>x \<sqsubseteq> approx i\<cdot>y) \<Longrightarrow> x \<sqsubseteq> y"
+lemma profinite_below_ext: "(\<And>i. approx i\<cdot>x \<sqsubseteq> approx i\<cdot>y) \<Longrightarrow> x \<sqsubseteq> y"
apply (subgoal_tac "(\<Squnion>i. approx i\<cdot>x) \<sqsubseteq> (\<Squnion>i. approx i\<cdot>y)", simp)
apply (rule lub_mono, simp, simp, simp)
done
--- a/src/HOLCF/Cfun.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Cfun.thy Mon May 11 17:20:52 2009 +0200
@@ -105,19 +105,19 @@
by (rule typedef_finite_po [OF type_definition_CFun])
instance "->" :: (finite_po, chfin) chfin
-by (rule typedef_chfin [OF type_definition_CFun less_CFun_def])
+by (rule typedef_chfin [OF type_definition_CFun below_CFun_def])
instance "->" :: (cpo, discrete_cpo) discrete_cpo
-by intro_classes (simp add: less_CFun_def Rep_CFun_inject)
+by intro_classes (simp add: below_CFun_def Rep_CFun_inject)
instance "->" :: (cpo, pcpo) pcpo
-by (rule typedef_pcpo [OF type_definition_CFun less_CFun_def UU_CFun])
+by (rule typedef_pcpo [OF type_definition_CFun below_CFun_def UU_CFun])
lemmas Rep_CFun_strict =
- typedef_Rep_strict [OF type_definition_CFun less_CFun_def UU_CFun]
+ typedef_Rep_strict [OF type_definition_CFun below_CFun_def UU_CFun]
lemmas Abs_CFun_strict =
- typedef_Abs_strict [OF type_definition_CFun less_CFun_def UU_CFun]
+ typedef_Abs_strict [OF type_definition_CFun below_CFun_def UU_CFun]
text {* function application is strict in its first argument *}
@@ -153,11 +153,11 @@
text {* Extensionality wrt. ordering for continuous functions *}
-lemma expand_cfun_less: "f \<sqsubseteq> g = (\<forall>x. f\<cdot>x \<sqsubseteq> g\<cdot>x)"
-by (simp add: less_CFun_def expand_fun_less)
+lemma expand_cfun_below: "f \<sqsubseteq> g = (\<forall>x. f\<cdot>x \<sqsubseteq> g\<cdot>x)"
+by (simp add: below_CFun_def expand_fun_below)
-lemma less_cfun_ext: "(\<And>x. f\<cdot>x \<sqsubseteq> g\<cdot>x) \<Longrightarrow> f \<sqsubseteq> g"
-by (simp add: expand_cfun_less)
+lemma below_cfun_ext: "(\<And>x. f\<cdot>x \<sqsubseteq> g\<cdot>x) \<Longrightarrow> f \<sqsubseteq> g"
+by (simp add: expand_cfun_below)
text {* Congruence for continuous function application *}
@@ -205,13 +205,13 @@
text {* monotonicity of application *}
lemma monofun_cfun_fun: "f \<sqsubseteq> g \<Longrightarrow> f\<cdot>x \<sqsubseteq> g\<cdot>x"
-by (simp add: expand_cfun_less)
+by (simp add: expand_cfun_below)
lemma monofun_cfun_arg: "x \<sqsubseteq> y \<Longrightarrow> f\<cdot>x \<sqsubseteq> f\<cdot>y"
by (rule monofun_Rep_CFun2 [THEN monofunE])
lemma monofun_cfun: "\<lbrakk>f \<sqsubseteq> g; x \<sqsubseteq> y\<rbrakk> \<Longrightarrow> f\<cdot>x \<sqsubseteq> g\<cdot>y"
-by (rule trans_less [OF monofun_cfun_fun monofun_cfun_arg])
+by (rule below_trans [OF monofun_cfun_fun monofun_cfun_arg])
text {* ch2ch - rules for the type @{typ "'a -> 'b"} *}
@@ -230,7 +230,7 @@
lemma ch2ch_LAM [simp]:
"\<lbrakk>\<And>x. chain (\<lambda>i. S i x); \<And>i. cont (\<lambda>x. S i x)\<rbrakk> \<Longrightarrow> chain (\<lambda>i. \<Lambda> x. S i x)"
-by (simp add: chain_def expand_cfun_less)
+by (simp add: chain_def expand_cfun_below)
text {* contlub, cont properties of @{term Rep_CFun} in both arguments *}
@@ -316,7 +316,7 @@
lemma cont2mono_LAM:
"\<lbrakk>\<And>x. cont (\<lambda>y. f x y); \<And>y. monofun (\<lambda>x. f x y)\<rbrakk>
\<Longrightarrow> monofun (\<lambda>x. \<Lambda> y. f x y)"
- unfolding monofun_def expand_cfun_less by simp
+ unfolding monofun_def expand_cfun_below by simp
text {* cont2cont Lemma for @{term "%x. LAM y. f x y"} *}
@@ -345,21 +345,11 @@
assumes f: "cont (\<lambda>p. f (fst p) (snd p))"
shows "cont (\<lambda>x. \<Lambda> y. f x y)"
proof (rule cont2cont_LAM)
- fix x :: 'a
- have "cont (\<lambda>y. (x, y))"
- by (rule cont_pair2)
- with f have "cont (\<lambda>y. f (fst (x, y)) (snd (x, y)))"
- by (rule cont2cont_app3)
- thus "cont (\<lambda>y. f x y)"
- by (simp only: fst_conv snd_conv)
+ fix x :: 'a show "cont (\<lambda>y. f x y)"
+ using f by (rule cont_fst_snd_D2)
next
- fix y :: 'b
- have "cont (\<lambda>x. (x, y))"
- by (rule cont_pair1)
- with f have "cont (\<lambda>x. f (fst (x, y)) (snd (x, y)))"
- by (rule cont2cont_app3)
- thus "cont (\<lambda>x. f x y)"
- by (simp only: fst_conv snd_conv)
+ fix y :: 'b show "cont (\<lambda>x. f x y)"
+ using f by (rule cont_fst_snd_D1)
qed
lemma cont2cont_LAM_discrete [cont2cont]:
@@ -375,7 +365,7 @@
lemma semi_monofun_Abs_CFun:
"\<lbrakk>cont f; cont g; f \<sqsubseteq> g\<rbrakk> \<Longrightarrow> Abs_CFun f \<sqsubseteq> Abs_CFun g"
-by (simp add: less_CFun_def Abs_CFun_inverse2)
+by (simp add: below_CFun_def Abs_CFun_inverse2)
text {* some lemmata for functions with flat/chfin domain/range types *}
@@ -411,7 +401,7 @@
apply simp
done
-lemma injection_less:
+lemma injection_below:
"\<forall>x. f\<cdot>(g\<cdot>x) = x \<Longrightarrow> (g\<cdot>x \<sqsubseteq> g\<cdot>y) = (x \<sqsubseteq> y)"
apply (rule iffI)
apply (drule_tac f=f in monofun_cfun_arg)
--- a/src/HOLCF/CompactBasis.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/CompactBasis.thy Mon May 11 17:20:52 2009 +0200
@@ -18,7 +18,7 @@
lemma compact_Rep_compact_basis: "compact (Rep_compact_basis a)"
by (rule Rep_compact_basis [unfolded mem_Collect_eq])
-instantiation compact_basis :: (profinite) sq_ord
+instantiation compact_basis :: (profinite) below
begin
definition
@@ -47,12 +47,12 @@
lemmas approx_Rep_compact_basis = Rep_compact_take [symmetric]
interpretation compact_basis:
- basis_take sq_le compact_take
+ basis_take below compact_take
proof
fix n :: nat and a :: "'a compact_basis"
show "compact_take n a \<sqsubseteq> a"
unfolding compact_le_def
- by (simp add: Rep_compact_take approx_less)
+ by (simp add: Rep_compact_take approx_below)
next
fix n :: nat and a :: "'a compact_basis"
show "compact_take n (compact_take n a) = compact_take n a"
@@ -93,15 +93,15 @@
"approximants = (\<lambda>x. {a. Rep_compact_basis a \<sqsubseteq> x})"
interpretation compact_basis:
- ideal_completion sq_le compact_take Rep_compact_basis approximants
+ ideal_completion below compact_take Rep_compact_basis approximants
proof
fix w :: 'a
- show "preorder.ideal sq_le (approximants w)"
- proof (rule sq_le.idealI)
+ show "preorder.ideal below (approximants w)"
+ proof (rule below.idealI)
show "\<exists>x. x \<in> approximants w"
unfolding approximants_def
apply (rule_tac x="Abs_compact_basis (approx 0\<cdot>w)" in exI)
- apply (simp add: Abs_compact_basis_inverse approx_less)
+ apply (simp add: Abs_compact_basis_inverse approx_below)
done
next
fix x y :: "'a compact_basis"
@@ -116,7 +116,7 @@
apply (clarify, rename_tac i j)
apply (rule_tac x="Abs_compact_basis (approx (max i j)\<cdot>w)" in exI)
apply (simp add: compact_le_def)
- apply (simp add: Abs_compact_basis_inverse approx_less)
+ apply (simp add: Abs_compact_basis_inverse approx_below)
apply (erule subst, erule subst)
apply (simp add: monofun_cfun chain_mono [OF chain_approx])
done
@@ -126,7 +126,7 @@
unfolding approximants_def
apply simp
apply (simp add: compact_le_def)
- apply (erule (1) trans_less)
+ apply (erule (1) below_trans)
done
qed
next
@@ -136,7 +136,7 @@
unfolding approximants_def
apply safe
apply (simp add: compactD2 [OF compact_Rep_compact_basis Y])
- apply (erule trans_less, rule is_ub_thelub [OF Y])
+ apply (erule below_trans, rule is_ub_thelub [OF Y])
done
next
fix a :: "'a compact_basis"
@@ -148,7 +148,7 @@
apply (subgoal_tac "(\<Squnion>i. approx i\<cdot>x) \<sqsubseteq> y", simp)
apply (rule admD, simp, simp)
apply (drule_tac c="Abs_compact_basis (approx i\<cdot>x)" in subsetD)
- apply (simp add: approximants_def Abs_compact_basis_inverse approx_less)
+ apply (simp add: approximants_def Abs_compact_basis_inverse approx_below)
apply (simp add: approximants_def Abs_compact_basis_inverse)
done
qed
@@ -288,7 +288,7 @@
apply (cut_tac a=a in compact_basis.take_covers)
apply (clarify, rule_tac x=n in exI)
apply (clarify, simp)
-apply (rule antisym_less)
+apply (rule below_antisym)
apply (rule compact_basis.take_less)
apply (drule_tac a=a in compact_basis.take_chain_le)
apply simp
--- a/src/HOLCF/Completion.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Completion.thy Mon May 11 17:20:52 2009 +0200
@@ -108,11 +108,11 @@
done
lemma typedef_ideal_po:
- fixes Abs :: "'a set \<Rightarrow> 'b::sq_ord"
+ fixes Abs :: "'a set \<Rightarrow> 'b::below"
assumes type: "type_definition Rep Abs {S. ideal S}"
- assumes less: "\<And>x y. x \<sqsubseteq> y \<longleftrightarrow> Rep x \<subseteq> Rep y"
+ assumes below: "\<And>x y. x \<sqsubseteq> y \<longleftrightarrow> Rep x \<subseteq> Rep y"
shows "OFCLASS('b, po_class)"
- apply (intro_classes, unfold less)
+ apply (intro_classes, unfold below)
apply (rule subset_refl)
apply (erule (1) subset_trans)
apply (rule type_definition.Rep_inject [OF type, THEN iffD1])
@@ -122,7 +122,7 @@
lemma
fixes Abs :: "'a set \<Rightarrow> 'b::po"
assumes type: "type_definition Rep Abs {S. ideal S}"
- assumes less: "\<And>x y. x \<sqsubseteq> y \<longleftrightarrow> Rep x \<subseteq> Rep y"
+ assumes below: "\<And>x y. x \<sqsubseteq> y \<longleftrightarrow> Rep x \<subseteq> Rep y"
assumes S: "chain S"
shows typedef_ideal_lub: "range S <<| Abs (\<Union>i. Rep (S i))"
and typedef_ideal_rep_contlub: "Rep (\<Squnion>i. S i) = (\<Union>i. Rep (S i))"
@@ -130,7 +130,7 @@
have 1: "ideal (\<Union>i. Rep (S i))"
apply (rule ideal_UN)
apply (rule type_definition.Rep [OF type, unfolded mem_Collect_eq])
- apply (subst less [symmetric])
+ apply (subst below [symmetric])
apply (erule chain_mono [OF S])
done
hence 2: "Rep (Abs (\<Union>i. Rep (S i))) = (\<Union>i. Rep (S i))"
@@ -138,8 +138,8 @@
show 3: "range S <<| Abs (\<Union>i. Rep (S i))"
apply (rule is_lubI)
apply (rule is_ubI)
- apply (simp add: less 2, fast)
- apply (simp add: less 2 is_ub_def, fast)
+ apply (simp add: below 2, fast)
+ apply (simp add: below 2 is_ub_def, fast)
done
hence 4: "(\<Squnion>i. S i) = Abs (\<Union>i. Rep (S i))"
by (rule thelubI)
@@ -150,16 +150,16 @@
lemma typedef_ideal_cpo:
fixes Abs :: "'a set \<Rightarrow> 'b::po"
assumes type: "type_definition Rep Abs {S. ideal S}"
- assumes less: "\<And>x y. x \<sqsubseteq> y \<longleftrightarrow> Rep x \<subseteq> Rep y"
+ assumes below: "\<And>x y. x \<sqsubseteq> y \<longleftrightarrow> Rep x \<subseteq> Rep y"
shows "OFCLASS('b, cpo_class)"
-by (default, rule exI, erule typedef_ideal_lub [OF type less])
+by (default, rule exI, erule typedef_ideal_lub [OF type below])
end
-interpretation sq_le: preorder "sq_le :: 'a::po \<Rightarrow> 'a \<Rightarrow> bool"
+interpretation below: preorder "below :: 'a::po \<Rightarrow> 'a \<Rightarrow> bool"
apply unfold_locales
-apply (rule refl_less)
-apply (erule (1) trans_less)
+apply (rule below_refl)
+apply (erule (1) below_trans)
done
subsection {* Lemmas about least upper bounds *}
@@ -229,43 +229,43 @@
apply (rule subsetI, rule UN_I [where a=0], simp_all)
done
-lemma less_def: "x \<sqsubseteq> y \<longleftrightarrow> rep x \<subseteq> rep y"
+lemma below_def: "x \<sqsubseteq> y \<longleftrightarrow> rep x \<subseteq> rep y"
by (rule iffI [OF rep_mono subset_repD])
lemma rep_eq: "rep x = {a. principal a \<sqsubseteq> x}"
-unfolding less_def rep_principal
+unfolding below_def rep_principal
apply safe
apply (erule (1) idealD3 [OF ideal_rep])
apply (erule subsetD, simp add: r_refl)
done
-lemma mem_rep_iff_principal_less: "a \<in> rep x \<longleftrightarrow> principal a \<sqsubseteq> x"
+lemma mem_rep_iff_principal_below: "a \<in> rep x \<longleftrightarrow> principal a \<sqsubseteq> x"
by (simp add: rep_eq)
-lemma principal_less_iff_mem_rep: "principal a \<sqsubseteq> x \<longleftrightarrow> a \<in> rep x"
+lemma principal_below_iff_mem_rep: "principal a \<sqsubseteq> x \<longleftrightarrow> a \<in> rep x"
by (simp add: rep_eq)
-lemma principal_less_iff [simp]: "principal a \<sqsubseteq> principal b \<longleftrightarrow> a \<preceq> b"
-by (simp add: principal_less_iff_mem_rep rep_principal)
+lemma principal_below_iff [simp]: "principal a \<sqsubseteq> principal b \<longleftrightarrow> a \<preceq> b"
+by (simp add: principal_below_iff_mem_rep rep_principal)
lemma principal_eq_iff: "principal a = principal b \<longleftrightarrow> a \<preceq> b \<and> b \<preceq> a"
-unfolding po_eq_conv [where 'a='b] principal_less_iff ..
+unfolding po_eq_conv [where 'a='b] principal_below_iff ..
lemma repD: "a \<in> rep x \<Longrightarrow> principal a \<sqsubseteq> x"
by (simp add: rep_eq)
lemma principal_mono: "a \<preceq> b \<Longrightarrow> principal a \<sqsubseteq> principal b"
-by (simp only: principal_less_iff)
+by (simp only: principal_below_iff)
-lemma lessI: "(\<And>a. principal a \<sqsubseteq> x \<Longrightarrow> principal a \<sqsubseteq> u) \<Longrightarrow> x \<sqsubseteq> u"
-unfolding principal_less_iff_mem_rep
-by (simp add: less_def subset_eq)
+lemma belowI: "(\<And>a. principal a \<sqsubseteq> x \<Longrightarrow> principal a \<sqsubseteq> u) \<Longrightarrow> x \<sqsubseteq> u"
+unfolding principal_below_iff_mem_rep
+by (simp add: below_def subset_eq)
lemma lub_principal_rep: "principal ` rep x <<| x"
apply (rule is_lubI)
apply (rule ub_imageI)
apply (erule repD)
-apply (subst less_def)
+apply (subst below_def)
apply (rule subsetI)
apply (drule (1) ub_imageD)
apply (simp add: rep_eq)
@@ -299,7 +299,7 @@
apply (rule is_lub_thelub0)
apply (rule basis_fun_lemma0, erule f_mono)
apply (rule is_ubI, clarsimp, rename_tac a)
- apply (rule trans_less [OF f_mono [OF take_chain]])
+ apply (rule below_trans [OF f_mono [OF take_chain]])
apply (rule is_ub_thelub0)
apply (rule basis_fun_lemma0, erule f_mono)
apply simp
@@ -313,7 +313,7 @@
apply (rule ub_imageI, rename_tac a)
apply (cut_tac a=a in take_covers, erule exE, rename_tac i)
apply (erule subst)
- apply (rule rev_trans_less)
+ apply (rule rev_below_trans)
apply (rule_tac x=i in is_ub_thelub)
apply (rule basis_fun_lemma1, erule f_mono)
apply (rule is_ub_thelub0)
@@ -324,7 +324,7 @@
apply (rule is_lub_thelub0)
apply (rule basis_fun_lemma0, erule f_mono)
apply (rule is_ubI, clarsimp, rename_tac a)
- apply (rule trans_less [OF f_mono [OF take_less]])
+ apply (rule below_trans [OF f_mono [OF take_less]])
apply (erule (1) ub_imageD)
done
@@ -350,7 +350,7 @@
apply (erule (1) subsetD [OF rep_mono])
apply (rule is_lub_thelub0 [OF lub ub_imageI])
apply (simp add: rep_contlub, clarify)
- apply (erule rev_trans_less [OF is_ub_thelub])
+ apply (erule rev_below_trans [OF is_ub_thelub])
apply (erule is_ub_thelub0 [OF lub imageI])
done
qed
@@ -367,21 +367,21 @@
lemma basis_fun_mono:
assumes f_mono: "\<And>a b. a \<preceq> b \<Longrightarrow> f a \<sqsubseteq> f b"
assumes g_mono: "\<And>a b. a \<preceq> b \<Longrightarrow> g a \<sqsubseteq> g b"
- assumes less: "\<And>a. f a \<sqsubseteq> g a"
+ assumes below: "\<And>a. f a \<sqsubseteq> g a"
shows "basis_fun f \<sqsubseteq> basis_fun g"
- apply (rule less_cfun_ext)
+ apply (rule below_cfun_ext)
apply (simp only: basis_fun_beta f_mono g_mono)
apply (rule is_lub_thelub0)
apply (rule basis_fun_lemma, erule f_mono)
apply (rule ub_imageI, rename_tac a)
- apply (rule trans_less [OF less])
+ apply (rule below_trans [OF below])
apply (rule is_ub_thelub0)
apply (rule basis_fun_lemma, erule g_mono)
apply (erule imageI)
done
lemma compact_principal [simp]: "compact (principal a)"
-by (rule compactI2, simp add: principal_less_iff_mem_rep rep_contlub)
+by (rule compactI2, simp add: principal_below_iff_mem_rep rep_contlub)
subsection {* Bifiniteness of ideal completions *}
--- a/src/HOLCF/Cont.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Cont.thy Mon May 11 17:20:52 2009 +0200
@@ -121,14 +121,14 @@
lemma contI2:
assumes mono: "monofun f"
- assumes less: "\<And>Y. \<lbrakk>chain Y; chain (\<lambda>i. f (Y i))\<rbrakk>
+ assumes below: "\<And>Y. \<lbrakk>chain Y; chain (\<lambda>i. f (Y i))\<rbrakk>
\<Longrightarrow> f (\<Squnion>i. Y i) \<sqsubseteq> (\<Squnion>i. f (Y i))"
shows "cont f"
apply (rule monocontlub2cont)
apply (rule mono)
apply (rule contlubI)
-apply (rule antisym_less)
-apply (rule less, assumption)
+apply (rule below_antisym)
+apply (rule below, assumption)
apply (erule ch2ch_monofun [OF mono])
apply (rule is_lub_thelub)
apply (erule ch2ch_monofun [OF mono])
@@ -144,7 +144,7 @@
( val name = "cont2cont" val description = "continuity intro rule" )
*}
-setup {* Cont2ContData.setup *}
+setup Cont2ContData.setup
text {*
Given the term @{term "cont f"}, the procedure tries to construct the
@@ -153,20 +153,13 @@
conditional rewrite rule with the unsolved subgoals as premises.
*}
-setup {*
-let
- fun solve_cont thy ss t =
+simproc_setup cont_proc ("cont f") = {*
+ fn phi => fn ss => fn ct =>
let
- val tr = instantiate' [] [SOME (cterm_of thy t)] Eq_TrueI;
+ val tr = instantiate' [] [SOME ct] @{thm Eq_TrueI};
val rules = Cont2ContData.get (Simplifier.the_context ss);
val tac = REPEAT_ALL_NEW (match_tac rules);
- in Option.map fst (Seq.pull (tac 1 tr)) end
-
- val proc =
- Simplifier.simproc @{theory} "cont_proc" ["cont f"] solve_cont;
-in
- Simplifier.map_simpset (fn ss => ss addsimprocs [proc])
-end
+ in SINGLE (tac 1) tr end
*}
subsection {* Continuity of basic functions *}
@@ -187,31 +180,31 @@
text {* application of functions is continuous *}
-lemma cont2cont_apply:
+lemma cont_apply:
fixes f :: "'a::cpo \<Rightarrow> 'b::cpo \<Rightarrow> 'c::cpo" and t :: "'a \<Rightarrow> 'b"
- assumes f1: "\<And>y. cont (\<lambda>x. f x y)"
- assumes f2: "\<And>x. cont (\<lambda>y. f x y)"
- assumes t: "cont (\<lambda>x. t x)"
+ assumes 1: "cont (\<lambda>x. t x)"
+ assumes 2: "\<And>x. cont (\<lambda>y. f x y)"
+ assumes 3: "\<And>y. cont (\<lambda>x. f x y)"
shows "cont (\<lambda>x. (f x) (t x))"
proof (rule monocontlub2cont [OF monofunI contlubI])
fix x y :: "'a" assume "x \<sqsubseteq> y"
then show "f x (t x) \<sqsubseteq> f y (t y)"
- by (auto intro: cont2monofunE [OF f1]
- cont2monofunE [OF f2]
- cont2monofunE [OF t]
- trans_less)
+ by (auto intro: cont2monofunE [OF 1]
+ cont2monofunE [OF 2]
+ cont2monofunE [OF 3]
+ below_trans)
next
fix Y :: "nat \<Rightarrow> 'a" assume "chain Y"
then show "f (\<Squnion>i. Y i) (t (\<Squnion>i. Y i)) = (\<Squnion>i. f (Y i) (t (Y i)))"
- by (simp only: cont2contlubE [OF t] ch2ch_cont [OF t]
- cont2contlubE [OF f1] ch2ch_cont [OF f1]
- cont2contlubE [OF f2] ch2ch_cont [OF f2]
+ by (simp only: cont2contlubE [OF 1] ch2ch_cont [OF 1]
+ cont2contlubE [OF 2] ch2ch_cont [OF 2]
+ cont2contlubE [OF 3] ch2ch_cont [OF 3]
diag_lub)
qed
-lemma cont2cont_compose:
+lemma cont_compose:
"\<lbrakk>cont c; cont (\<lambda>x. f x)\<rbrakk> \<Longrightarrow> cont (\<lambda>x. c (f x))"
-by (rule cont2cont_apply [OF cont_const])
+by (rule cont_apply [OF _ _ cont_const])
text {* if-then-else is continuous *}
--- a/src/HOLCF/ConvexPD.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/ConvexPD.thy Mon May 11 17:20:52 2009 +0200
@@ -144,7 +144,7 @@
"{S::'a pd_basis set. convex_le.ideal S}"
by (fast intro: convex_le.ideal_principal)
-instantiation convex_pd :: (profinite) sq_ord
+instantiation convex_pd :: (profinite) below
begin
definition
@@ -155,16 +155,16 @@
instance convex_pd :: (profinite) po
by (rule convex_le.typedef_ideal_po
- [OF type_definition_convex_pd sq_le_convex_pd_def])
+ [OF type_definition_convex_pd below_convex_pd_def])
instance convex_pd :: (profinite) cpo
by (rule convex_le.typedef_ideal_cpo
- [OF type_definition_convex_pd sq_le_convex_pd_def])
+ [OF type_definition_convex_pd below_convex_pd_def])
lemma Rep_convex_pd_lub:
"chain Y \<Longrightarrow> Rep_convex_pd (\<Squnion>i. Y i) = (\<Union>i. Rep_convex_pd (Y i))"
by (rule convex_le.typedef_ideal_rep_contlub
- [OF type_definition_convex_pd sq_le_convex_pd_def])
+ [OF type_definition_convex_pd below_convex_pd_def])
lemma ideal_Rep_convex_pd: "convex_le.ideal (Rep_convex_pd xs)"
by (rule Rep_convex_pd [unfolded mem_Collect_eq])
@@ -190,7 +190,7 @@
apply (rule ideal_Rep_convex_pd)
apply (erule Rep_convex_pd_lub)
apply (rule Rep_convex_principal)
-apply (simp only: sq_le_convex_pd_def)
+apply (simp only: below_convex_pd_def)
done
text {* Convex powerdomain is pointed *}
@@ -311,7 +311,7 @@
lemmas convex_plus_aci =
convex_plus_ac convex_plus_absorb convex_plus_left_absorb
-lemma convex_unit_less_plus_iff [simp]:
+lemma convex_unit_below_plus_iff [simp]:
"{x}\<natural> \<sqsubseteq> ys +\<natural> zs \<longleftrightarrow> {x}\<natural> \<sqsubseteq> ys \<and> {x}\<natural> \<sqsubseteq> zs"
apply (rule iffI)
apply (subgoal_tac
@@ -329,7 +329,7 @@
apply (erule (1) monofun_cfun [OF monofun_cfun_arg])
done
-lemma convex_plus_less_unit_iff [simp]:
+lemma convex_plus_below_unit_iff [simp]:
"xs +\<natural> ys \<sqsubseteq> {z}\<natural> \<longleftrightarrow> xs \<sqsubseteq> {z}\<natural> \<and> ys \<sqsubseteq> {z}\<natural>"
apply (rule iffI)
apply (subgoal_tac
@@ -347,9 +347,9 @@
apply (erule (1) monofun_cfun [OF monofun_cfun_arg])
done
-lemma convex_unit_less_iff [simp]: "{x}\<natural> \<sqsubseteq> {y}\<natural> \<longleftrightarrow> x \<sqsubseteq> y"
+lemma convex_unit_below_iff [simp]: "{x}\<natural> \<sqsubseteq> {y}\<natural> \<longleftrightarrow> x \<sqsubseteq> y"
apply (rule iffI)
- apply (rule profinite_less_ext)
+ apply (rule profinite_below_ext)
apply (drule_tac f="approx i" in monofun_cfun_arg, simp)
apply (cut_tac x="approx i\<cdot>x" in compact_basis.compact_imp_principal, simp)
apply (cut_tac x="approx i\<cdot>y" in compact_basis.compact_imp_principal, simp)
@@ -433,12 +433,12 @@
lemma monofun_LAM:
"\<lbrakk>cont f; cont g; \<And>x. f x \<sqsubseteq> g x\<rbrakk> \<Longrightarrow> (\<Lambda> x. f x) \<sqsubseteq> (\<Lambda> x. g x)"
-by (simp add: expand_cfun_less)
+by (simp add: expand_cfun_below)
lemma convex_bind_basis_mono:
"t \<le>\<natural> u \<Longrightarrow> convex_bind_basis t \<sqsubseteq> convex_bind_basis u"
apply (erule convex_le_induct)
-apply (erule (1) trans_less)
+apply (erule (1) below_trans)
apply (simp add: monofun_LAM monofun_cfun)
apply (simp add: monofun_LAM monofun_cfun)
done
@@ -606,12 +606,12 @@
text {* Ordering property *}
-lemma convex_pd_less_iff:
+lemma convex_pd_below_iff:
"(xs \<sqsubseteq> ys) =
(convex_to_upper\<cdot>xs \<sqsubseteq> convex_to_upper\<cdot>ys \<and>
convex_to_lower\<cdot>xs \<sqsubseteq> convex_to_lower\<cdot>ys)"
apply (safe elim!: monofun_cfun_arg)
- apply (rule profinite_less_ext)
+ apply (rule profinite_below_ext)
apply (drule_tac f="approx i" in monofun_cfun_arg)
apply (drule_tac f="approx i" in monofun_cfun_arg)
apply (cut_tac x="approx i\<cdot>xs" in convex_pd.compact_imp_principal, simp)
@@ -620,19 +620,19 @@
apply (simp add: approx_convex_to_upper approx_convex_to_lower convex_le_def)
done
-lemmas convex_plus_less_plus_iff =
- convex_pd_less_iff [where xs="xs +\<natural> ys" and ys="zs +\<natural> ws", standard]
+lemmas convex_plus_below_plus_iff =
+ convex_pd_below_iff [where xs="xs +\<natural> ys" and ys="zs +\<natural> ws", standard]
-lemmas convex_pd_less_simps =
- convex_unit_less_plus_iff
- convex_plus_less_unit_iff
- convex_plus_less_plus_iff
- convex_unit_less_iff
+lemmas convex_pd_below_simps =
+ convex_unit_below_plus_iff
+ convex_plus_below_unit_iff
+ convex_plus_below_plus_iff
+ convex_unit_below_iff
convex_to_upper_unit
convex_to_upper_plus
convex_to_lower_unit
convex_to_lower_plus
- upper_pd_less_simps
- lower_pd_less_simps
+ upper_pd_below_simps
+ lower_pd_below_simps
end
--- a/src/HOLCF/Cprod.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Cprod.thy Mon May 11 17:20:52 2009 +0200
@@ -68,7 +68,7 @@
lemma cpair_eq [iff]: "(<a, b> = <a', b'>) = (a = a' \<and> b = b')"
by (simp add: cpair_eq_pair)
-lemma cpair_less [iff]: "(<a, b> \<sqsubseteq> <a', b'>) = (a \<sqsubseteq> a' \<and> b \<sqsubseteq> b')"
+lemma cpair_below [iff]: "(<a, b> \<sqsubseteq> <a', b'>) = (a \<sqsubseteq> a' \<and> b \<sqsubseteq> b')"
by (simp add: cpair_eq_pair)
lemma cpair_defined_iff [iff]: "(<x, y> = \<bottom>) = (x = \<bottom> \<and> y = \<bottom>)"
@@ -107,23 +107,23 @@
lemmas surjective_pairing_Cprod2 = cpair_cfst_csnd
-lemma less_cprod: "x \<sqsubseteq> y = (cfst\<cdot>x \<sqsubseteq> cfst\<cdot>y \<and> csnd\<cdot>x \<sqsubseteq> csnd\<cdot>y)"
-by (simp add: less_cprod_def cfst_def csnd_def cont_fst cont_snd)
+lemma below_cprod: "x \<sqsubseteq> y = (cfst\<cdot>x \<sqsubseteq> cfst\<cdot>y \<and> csnd\<cdot>x \<sqsubseteq> csnd\<cdot>y)"
+by (simp add: below_prod_def cfst_def csnd_def cont_fst cont_snd)
lemma eq_cprod: "(x = y) = (cfst\<cdot>x = cfst\<cdot>y \<and> csnd\<cdot>x = csnd\<cdot>y)"
-by (auto simp add: po_eq_conv less_cprod)
+by (auto simp add: po_eq_conv below_cprod)
-lemma cfst_less_iff: "cfst\<cdot>x \<sqsubseteq> y = x \<sqsubseteq> <y, csnd\<cdot>x>"
-by (simp add: less_cprod)
+lemma cfst_below_iff: "cfst\<cdot>x \<sqsubseteq> y = x \<sqsubseteq> <y, csnd\<cdot>x>"
+by (simp add: below_cprod)
-lemma csnd_less_iff: "csnd\<cdot>x \<sqsubseteq> y = x \<sqsubseteq> <cfst\<cdot>x, y>"
-by (simp add: less_cprod)
+lemma csnd_below_iff: "csnd\<cdot>x \<sqsubseteq> y = x \<sqsubseteq> <cfst\<cdot>x, y>"
+by (simp add: below_cprod)
lemma compact_cfst: "compact x \<Longrightarrow> compact (cfst\<cdot>x)"
-by (rule compactI, simp add: cfst_less_iff)
+by (rule compactI, simp add: cfst_below_iff)
lemma compact_csnd: "compact x \<Longrightarrow> compact (csnd\<cdot>x)"
-by (rule compactI, simp add: csnd_less_iff)
+by (rule compactI, simp add: csnd_below_iff)
lemma compact_cpair: "\<lbrakk>compact x; compact y\<rbrakk> \<Longrightarrow> compact <x, y>"
by (simp add: cpair_eq_pair)
--- a/src/HOLCF/Deflation.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Deflation.thy Mon May 11 17:20:52 2009 +0200
@@ -15,11 +15,11 @@
locale deflation =
fixes d :: "'a \<rightarrow> 'a"
assumes idem: "\<And>x. d\<cdot>(d\<cdot>x) = d\<cdot>x"
- assumes less: "\<And>x. d\<cdot>x \<sqsubseteq> x"
+ assumes below: "\<And>x. d\<cdot>x \<sqsubseteq> x"
begin
-lemma less_ID: "d \<sqsubseteq> ID"
-by (rule less_cfun_ext, simp add: less)
+lemma below_ID: "d \<sqsubseteq> ID"
+by (rule below_cfun_ext, simp add: below)
text {* The set of fixed points is the same as the range. *}
@@ -34,18 +34,18 @@
the subset ordering of their sets of fixed-points.
*}
-lemma lessI:
+lemma belowI:
assumes f: "\<And>x. d\<cdot>x = x \<Longrightarrow> f\<cdot>x = x" shows "d \<sqsubseteq> f"
-proof (rule less_cfun_ext)
+proof (rule below_cfun_ext)
fix x
- from less have "f\<cdot>(d\<cdot>x) \<sqsubseteq> f\<cdot>x" by (rule monofun_cfun_arg)
+ from below have "f\<cdot>(d\<cdot>x) \<sqsubseteq> f\<cdot>x" by (rule monofun_cfun_arg)
also from idem have "f\<cdot>(d\<cdot>x) = d\<cdot>x" by (rule f)
finally show "d\<cdot>x \<sqsubseteq> f\<cdot>x" .
qed
-lemma lessD: "\<lbrakk>f \<sqsubseteq> d; f\<cdot>x = x\<rbrakk> \<Longrightarrow> d\<cdot>x = x"
-proof (rule antisym_less)
- from less show "d\<cdot>x \<sqsubseteq> x" .
+lemma belowD: "\<lbrakk>f \<sqsubseteq> d; f\<cdot>x = x\<rbrakk> \<Longrightarrow> d\<cdot>x = x"
+proof (rule below_antisym)
+ from below show "d\<cdot>x \<sqsubseteq> x" .
next
assume "f \<sqsubseteq> d"
hence "f\<cdot>x \<sqsubseteq> d\<cdot>x" by (rule monofun_cfun_fun)
@@ -64,11 +64,11 @@
lemma deflation_UU: "deflation \<bottom>"
by (simp add: deflation.intro)
-lemma deflation_less_iff:
+lemma deflation_below_iff:
"\<lbrakk>deflation p; deflation q\<rbrakk> \<Longrightarrow> p \<sqsubseteq> q \<longleftrightarrow> (\<forall>x. p\<cdot>x = x \<longrightarrow> q\<cdot>x = x)"
apply safe
- apply (simp add: deflation.lessD)
- apply (simp add: deflation.lessI)
+ apply (simp add: deflation.belowD)
+ apply (simp add: deflation.belowI)
done
text {*
@@ -76,13 +76,13 @@
the lesser of the two (if they are comparable).
*}
-lemma deflation_less_comp1:
+lemma deflation_below_comp1:
assumes "deflation f"
assumes "deflation g"
shows "f \<sqsubseteq> g \<Longrightarrow> f\<cdot>(g\<cdot>x) = f\<cdot>x"
-proof (rule antisym_less)
+proof (rule below_antisym)
interpret g: deflation g by fact
- from g.less show "f\<cdot>(g\<cdot>x) \<sqsubseteq> f\<cdot>x" by (rule monofun_cfun_arg)
+ from g.below show "f\<cdot>(g\<cdot>x) \<sqsubseteq> f\<cdot>x" by (rule monofun_cfun_arg)
next
interpret f: deflation f by fact
assume "f \<sqsubseteq> g" hence "f\<cdot>x \<sqsubseteq> g\<cdot>x" by (rule monofun_cfun_fun)
@@ -91,9 +91,9 @@
finally show "f\<cdot>x \<sqsubseteq> f\<cdot>(g\<cdot>x)" .
qed
-lemma deflation_less_comp2:
+lemma deflation_below_comp2:
"\<lbrakk>deflation f; deflation g; f \<sqsubseteq> g\<rbrakk> \<Longrightarrow> g\<cdot>(f\<cdot>x) = f\<cdot>x"
-by (simp only: deflation.lessD deflation.idem)
+by (simp only: deflation.belowD deflation.idem)
subsection {* Deflations with finite range *}
@@ -143,7 +143,7 @@
hence "d\<cdot>x \<sqsubseteq> d\<cdot>(Y j)"
using j by simp
hence "d\<cdot>x \<sqsubseteq> Y j"
- using less by (rule trans_less)
+ using below by (rule below_trans)
thus "\<exists>j. d\<cdot>x \<sqsubseteq> Y j" ..
qed
@@ -155,10 +155,10 @@
locale ep_pair =
fixes e :: "'a \<rightarrow> 'b" and p :: "'b \<rightarrow> 'a"
assumes e_inverse [simp]: "\<And>x. p\<cdot>(e\<cdot>x) = x"
- and e_p_less: "\<And>y. e\<cdot>(p\<cdot>y) \<sqsubseteq> y"
+ and e_p_below: "\<And>y. e\<cdot>(p\<cdot>y) \<sqsubseteq> y"
begin
-lemma e_less_iff [simp]: "e\<cdot>x \<sqsubseteq> e\<cdot>y \<longleftrightarrow> x \<sqsubseteq> y"
+lemma e_below_iff [simp]: "e\<cdot>x \<sqsubseteq> e\<cdot>y \<longleftrightarrow> x \<sqsubseteq> y"
proof
assume "e\<cdot>x \<sqsubseteq> e\<cdot>y"
hence "p\<cdot>(e\<cdot>x) \<sqsubseteq> p\<cdot>(e\<cdot>y)" by (rule monofun_cfun_arg)
@@ -169,7 +169,7 @@
qed
lemma e_eq_iff [simp]: "e\<cdot>x = e\<cdot>y \<longleftrightarrow> x = y"
-unfolding po_eq_conv e_less_iff ..
+unfolding po_eq_conv e_below_iff ..
lemma p_eq_iff:
"\<lbrakk>e\<cdot>(p\<cdot>x) = x; e\<cdot>(p\<cdot>y) = y\<rbrakk> \<Longrightarrow> p\<cdot>x = p\<cdot>y \<longleftrightarrow> x = y"
@@ -178,7 +178,7 @@
lemma p_inverse: "(\<exists>x. y = e\<cdot>x) = (e\<cdot>(p\<cdot>y) = y)"
by (auto, rule exI, erule sym)
-lemma e_less_iff_less_p: "e\<cdot>x \<sqsubseteq> y \<longleftrightarrow> x \<sqsubseteq> p\<cdot>y"
+lemma e_below_iff_below_p: "e\<cdot>x \<sqsubseteq> y \<longleftrightarrow> x \<sqsubseteq> p\<cdot>y"
proof
assume "e\<cdot>x \<sqsubseteq> y"
then have "p\<cdot>(e\<cdot>x) \<sqsubseteq> p\<cdot>y" by (rule monofun_cfun_arg)
@@ -186,7 +186,7 @@
next
assume "x \<sqsubseteq> p\<cdot>y"
then have "e\<cdot>x \<sqsubseteq> e\<cdot>(p\<cdot>y)" by (rule monofun_cfun_arg)
- then show "e\<cdot>x \<sqsubseteq> y" using e_p_less by (rule trans_less)
+ then show "e\<cdot>x \<sqsubseteq> y" using e_p_below by (rule below_trans)
qed
lemma compact_e_rev: "compact (e\<cdot>x) \<Longrightarrow> compact x"
@@ -203,7 +203,7 @@
assume "compact x"
hence "adm (\<lambda>y. \<not> x \<sqsubseteq> y)" by (rule compactD)
hence "adm (\<lambda>y. \<not> x \<sqsubseteq> p\<cdot>y)" by (rule adm_subst [OF cont_Rep_CFun2])
- hence "adm (\<lambda>y. \<not> e\<cdot>x \<sqsubseteq> y)" by (simp add: e_less_iff_less_p)
+ hence "adm (\<lambda>y. \<not> e\<cdot>x \<sqsubseteq> y)" by (simp add: e_below_iff_below_p)
thus "compact (e\<cdot>x)" by (rule compactI)
qed
@@ -213,7 +213,7 @@
text {* Deflations from ep-pairs *}
lemma deflation_e_p: "deflation (e oo p)"
-by (simp add: deflation.intro e_p_less)
+by (simp add: deflation.intro e_p_below)
lemma deflation_e_d_p:
assumes "deflation d"
@@ -224,7 +224,7 @@
show "(e oo d oo p)\<cdot>((e oo d oo p)\<cdot>x) = (e oo d oo p)\<cdot>x"
by (simp add: idem)
show "(e oo d oo p)\<cdot>x \<sqsubseteq> x"
- by (simp add: e_less_iff_less_p less)
+ by (simp add: e_below_iff_below_p below)
qed
lemma finite_deflation_e_d_p:
@@ -236,7 +236,7 @@
show "(e oo d oo p)\<cdot>((e oo d oo p)\<cdot>x) = (e oo d oo p)\<cdot>x"
by (simp add: idem)
show "(e oo d oo p)\<cdot>x \<sqsubseteq> x"
- by (simp add: e_less_iff_less_p less)
+ by (simp add: e_below_iff_below_p below)
have "finite ((\<lambda>x. e\<cdot>x) ` (\<lambda>x. d\<cdot>x) ` range (\<lambda>x. p\<cdot>x))"
by (simp add: finite_image)
hence "finite (range (\<lambda>x. (e oo d oo p)\<cdot>x))"
@@ -254,24 +254,24 @@
{
fix x
have "d\<cdot>(e\<cdot>x) \<sqsubseteq> e\<cdot>x"
- by (rule d.less)
+ by (rule d.below)
hence "p\<cdot>(d\<cdot>(e\<cdot>x)) \<sqsubseteq> p\<cdot>(e\<cdot>x)"
by (rule monofun_cfun_arg)
hence "(p oo d oo e)\<cdot>x \<sqsubseteq> x"
by simp
}
- note p_d_e_less = this
+ note p_d_e_below = this
show ?thesis
proof
fix x
show "(p oo d oo e)\<cdot>x \<sqsubseteq> x"
- by (rule p_d_e_less)
+ by (rule p_d_e_below)
next
fix x
show "(p oo d oo e)\<cdot>((p oo d oo e)\<cdot>x) = (p oo d oo e)\<cdot>x"
- proof (rule antisym_less)
+ proof (rule below_antisym)
show "(p oo d oo e)\<cdot>((p oo d oo e)\<cdot>x) \<sqsubseteq> (p oo d oo e)\<cdot>x"
- by (rule p_d_e_less)
+ by (rule p_d_e_below)
have "p\<cdot>(d\<cdot>(d\<cdot>(d\<cdot>(e\<cdot>x)))) \<sqsubseteq> p\<cdot>(d\<cdot>(e\<cdot>(p\<cdot>(d\<cdot>(e\<cdot>x)))))"
by (intro monofun_cfun_arg d)
hence "p\<cdot>(d\<cdot>(e\<cdot>x)) \<sqsubseteq> p\<cdot>(d\<cdot>(e\<cdot>(p\<cdot>(d\<cdot>(e\<cdot>x)))))"
@@ -315,29 +315,29 @@
lemma ep_pair_unique_e_lemma:
assumes "ep_pair e1 p" and "ep_pair e2 p"
shows "e1 \<sqsubseteq> e2"
-proof (rule less_cfun_ext)
+proof (rule below_cfun_ext)
interpret e1: ep_pair e1 p by fact
interpret e2: ep_pair e2 p by fact
fix x
have "e1\<cdot>(p\<cdot>(e2\<cdot>x)) \<sqsubseteq> e2\<cdot>x"
- by (rule e1.e_p_less)
+ by (rule e1.e_p_below)
thus "e1\<cdot>x \<sqsubseteq> e2\<cdot>x"
by (simp only: e2.e_inverse)
qed
lemma ep_pair_unique_e:
"\<lbrakk>ep_pair e1 p; ep_pair e2 p\<rbrakk> \<Longrightarrow> e1 = e2"
-by (fast intro: antisym_less elim: ep_pair_unique_e_lemma)
+by (fast intro: below_antisym elim: ep_pair_unique_e_lemma)
lemma ep_pair_unique_p_lemma:
assumes "ep_pair e p1" and "ep_pair e p2"
shows "p1 \<sqsubseteq> p2"
-proof (rule less_cfun_ext)
+proof (rule below_cfun_ext)
interpret p1: ep_pair e p1 by fact
interpret p2: ep_pair e p2 by fact
fix x
have "e\<cdot>(p1\<cdot>x) \<sqsubseteq> x"
- by (rule p1.e_p_less)
+ by (rule p1.e_p_below)
hence "p2\<cdot>(e\<cdot>(p1\<cdot>x)) \<sqsubseteq> p2\<cdot>x"
by (rule monofun_cfun_arg)
thus "p1\<cdot>x \<sqsubseteq> p2\<cdot>x"
@@ -346,7 +346,7 @@
lemma ep_pair_unique_p:
"\<lbrakk>ep_pair e p1; ep_pair e p2\<rbrakk> \<Longrightarrow> p1 = p2"
-by (fast intro: antisym_less elim: ep_pair_unique_p_lemma)
+by (fast intro: below_antisym elim: ep_pair_unique_p_lemma)
subsection {* Composing ep-pairs *}
@@ -363,11 +363,11 @@
show "(p1 oo p2)\<cdot>((e2 oo e1)\<cdot>x) = x"
by simp
have "e1\<cdot>(p1\<cdot>(p2\<cdot>y)) \<sqsubseteq> p2\<cdot>y"
- by (rule ep1.e_p_less)
+ by (rule ep1.e_p_below)
hence "e2\<cdot>(e1\<cdot>(p1\<cdot>(p2\<cdot>y))) \<sqsubseteq> e2\<cdot>(p2\<cdot>y)"
by (rule monofun_cfun_arg)
also have "e2\<cdot>(p2\<cdot>y) \<sqsubseteq> y"
- by (rule ep2.e_p_less)
+ by (rule ep2.e_p_below)
finally show "(e2 oo e1)\<cdot>((p1 oo p2)\<cdot>y) \<sqsubseteq> y"
by simp
qed
@@ -381,7 +381,7 @@
proof -
have "\<bottom> \<sqsubseteq> p\<cdot>\<bottom>" by (rule minimal)
hence "e\<cdot>\<bottom> \<sqsubseteq> e\<cdot>(p\<cdot>\<bottom>)" by (rule monofun_cfun_arg)
- also have "e\<cdot>(p\<cdot>\<bottom>) \<sqsubseteq> \<bottom>" by (rule e_p_less)
+ also have "e\<cdot>(p\<cdot>\<bottom>) \<sqsubseteq> \<bottom>" by (rule e_p_below)
finally show "e\<cdot>\<bottom> = \<bottom>" by simp
qed
--- a/src/HOLCF/Discrete.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Discrete.thy Mon May 11 17:20:52 2009 +0200
@@ -12,21 +12,21 @@
subsection {* Type @{typ "'a discr"} is a discrete cpo *}
-instantiation discr :: (type) sq_ord
+instantiation discr :: (type) below
begin
definition
- less_discr_def:
+ below_discr_def:
"(op \<sqsubseteq> :: 'a discr \<Rightarrow> 'a discr \<Rightarrow> bool) = (op =)"
instance ..
end
instance discr :: (type) discrete_cpo
-by intro_classes (simp add: less_discr_def)
+by intro_classes (simp add: below_discr_def)
-lemma discr_less_eq [iff]: "((x::('a::type)discr) << y) = (x = y)"
-by simp
+lemma discr_below_eq [iff]: "((x::('a::type)discr) << y) = (x = y)"
+by simp (* FIXME: same discrete_cpo - remove? is [iff] important? *)
subsection {* Type @{typ "'a discr"} is a cpo *}
--- a/src/HOLCF/Domain.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Domain.thy Mon May 11 17:20:52 2009 +0200
@@ -6,6 +6,14 @@
theory Domain
imports Ssum Sprod Up One Tr Fixrec
+uses
+ ("Tools/cont_consts.ML")
+ ("Tools/cont_proc.ML")
+ ("Tools/domain/domain_library.ML")
+ ("Tools/domain/domain_syntax.ML")
+ ("Tools/domain/domain_axioms.ML")
+ ("Tools/domain/domain_theorems.ML")
+ ("Tools/domain/domain_extender.ML")
begin
defaultsort pcpo
@@ -25,7 +33,7 @@
lemma swap: "iso rep abs"
by (rule iso.intro [OF rep_iso abs_iso])
-lemma abs_less: "(abs\<cdot>x \<sqsubseteq> abs\<cdot>y) = (x \<sqsubseteq> y)"
+lemma abs_below: "(abs\<cdot>x \<sqsubseteq> abs\<cdot>y) = (x \<sqsubseteq> y)"
proof
assume "abs\<cdot>x \<sqsubseteq> abs\<cdot>y"
then have "rep\<cdot>(abs\<cdot>x) \<sqsubseteq> rep\<cdot>(abs\<cdot>y)" by (rule monofun_cfun_arg)
@@ -35,11 +43,11 @@
then show "abs\<cdot>x \<sqsubseteq> abs\<cdot>y" by (rule monofun_cfun_arg)
qed
-lemma rep_less: "(rep\<cdot>x \<sqsubseteq> rep\<cdot>y) = (x \<sqsubseteq> y)"
- by (rule iso.abs_less [OF swap])
+lemma rep_below: "(rep\<cdot>x \<sqsubseteq> rep\<cdot>y) = (x \<sqsubseteq> y)"
+ by (rule iso.abs_below [OF swap])
lemma abs_eq: "(abs\<cdot>x = abs\<cdot>y) = (x = y)"
- by (simp add: po_eq_conv abs_less)
+ by (simp add: po_eq_conv abs_below)
lemma rep_eq: "(rep\<cdot>x = rep\<cdot>y) = (x = y)"
by (rule iso.abs_eq [OF swap])
@@ -83,7 +91,7 @@
assume "adm (\<lambda>y. \<not> abs\<cdot>x \<sqsubseteq> y)"
with cont_Rep_CFun2
have "adm (\<lambda>y. \<not> abs\<cdot>x \<sqsubseteq> abs\<cdot>y)" by (rule adm_subst)
- then show "adm (\<lambda>y. \<not> x \<sqsubseteq> y)" using abs_less by simp
+ then show "adm (\<lambda>y. \<not> x \<sqsubseteq> y)" using abs_below by simp
qed
lemma compact_rep_rev: "compact (rep\<cdot>x) \<Longrightarrow> compact x"
@@ -193,4 +201,24 @@
lemmas exh_casedists = exh_casedist1 exh_casedist2 exh_casedist3
+
+subsection {* Installing the domain package *}
+
+lemmas con_strict_rules =
+ sinl_strict sinr_strict spair_strict1 spair_strict2
+
+lemmas con_defin_rules =
+ sinl_defined sinr_defined spair_defined up_defined ONE_defined
+
+lemmas con_defined_iff_rules =
+ sinl_defined_iff sinr_defined_iff spair_strict_iff up_defined ONE_defined
+
+use "Tools/cont_consts.ML"
+use "Tools/cont_proc.ML"
+use "Tools/domain/domain_library.ML"
+use "Tools/domain/domain_syntax.ML"
+use "Tools/domain/domain_axioms.ML"
+use "Tools/domain/domain_theorems.ML"
+use "Tools/domain/domain_extender.ML"
+
end
--- a/src/HOLCF/FOCUS/Stream_adm.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/FOCUS/Stream_adm.thy Mon May 11 17:20:52 2009 +0200
@@ -50,11 +50,7 @@
apply ( erule spec)
apply ( assumption)
apply ( assumption)
-apply (drule not_ex [THEN iffD1])
-apply (subst slen_infinite)
-apply (erule thin_rl)
-apply (erule_tac x = j in allE)
-apply auto
+apply (metis inat_ord_code(4) slen_infinite)
done
(* should be without reference to stream length? *)
--- a/src/HOLCF/Ffun.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Ffun.thy Mon May 11 17:20:52 2009 +0200
@@ -10,11 +10,11 @@
subsection {* Full function space is a partial order *}
-instantiation "fun" :: (type, sq_ord) sq_ord
+instantiation "fun" :: (type, below) below
begin
definition
- less_fun_def: "(op \<sqsubseteq>) \<equiv> (\<lambda>f g. \<forall>x. f x \<sqsubseteq> g x)"
+ below_fun_def: "(op \<sqsubseteq>) \<equiv> (\<lambda>f g. \<forall>x. f x \<sqsubseteq> g x)"
instance ..
end
@@ -23,45 +23,45 @@
proof
fix f :: "'a \<Rightarrow> 'b"
show "f \<sqsubseteq> f"
- by (simp add: less_fun_def)
+ by (simp add: below_fun_def)
next
fix f g :: "'a \<Rightarrow> 'b"
assume "f \<sqsubseteq> g" and "g \<sqsubseteq> f" thus "f = g"
- by (simp add: less_fun_def expand_fun_eq antisym_less)
+ by (simp add: below_fun_def expand_fun_eq below_antisym)
next
fix f g h :: "'a \<Rightarrow> 'b"
assume "f \<sqsubseteq> g" and "g \<sqsubseteq> h" thus "f \<sqsubseteq> h"
- unfolding less_fun_def by (fast elim: trans_less)
+ unfolding below_fun_def by (fast elim: below_trans)
qed
text {* make the symbol @{text "<<"} accessible for type fun *}
-lemma expand_fun_less: "(f \<sqsubseteq> g) = (\<forall>x. f x \<sqsubseteq> g x)"
-by (simp add: less_fun_def)
+lemma expand_fun_below: "(f \<sqsubseteq> g) = (\<forall>x. f x \<sqsubseteq> g x)"
+by (simp add: below_fun_def)
-lemma less_fun_ext: "(\<And>x. f x \<sqsubseteq> g x) \<Longrightarrow> f \<sqsubseteq> g"
-by (simp add: less_fun_def)
+lemma below_fun_ext: "(\<And>x. f x \<sqsubseteq> g x) \<Longrightarrow> f \<sqsubseteq> g"
+by (simp add: below_fun_def)
subsection {* Full function space is chain complete *}
text {* function application is monotone *}
lemma monofun_app: "monofun (\<lambda>f. f x)"
-by (rule monofunI, simp add: less_fun_def)
+by (rule monofunI, simp add: below_fun_def)
text {* chains of functions yield chains in the po range *}
lemma ch2ch_fun: "chain S \<Longrightarrow> chain (\<lambda>i. S i x)"
-by (simp add: chain_def less_fun_def)
+by (simp add: chain_def below_fun_def)
lemma ch2ch_lambda: "(\<And>x. chain (\<lambda>i. S i x)) \<Longrightarrow> chain S"
-by (simp add: chain_def less_fun_def)
+by (simp add: chain_def below_fun_def)
text {* upper bounds of function chains yield upper bound in the po range *}
lemma ub2ub_fun:
"range S <| u \<Longrightarrow> range (\<lambda>i. S i x) <| u x"
-by (auto simp add: is_ub_def less_fun_def)
+by (auto simp add: is_ub_def below_fun_def)
text {* Type @{typ "'a::type => 'b::cpo"} is chain complete *}
@@ -70,9 +70,9 @@
shows "range Y <<| f"
apply (rule is_lubI)
apply (rule ub_rangeI)
-apply (rule less_fun_ext)
+apply (rule below_fun_ext)
apply (rule is_ub_lub [OF f])
-apply (rule less_fun_ext)
+apply (rule below_fun_ext)
apply (rule is_lub_lub [OF f])
apply (erule ub2ub_fun)
done
@@ -103,7 +103,7 @@
proof
fix f g :: "'a \<Rightarrow> 'b"
show "f \<sqsubseteq> g \<longleftrightarrow> f = g"
- unfolding expand_fun_less expand_fun_eq
+ unfolding expand_fun_below expand_fun_eq
by simp
qed
@@ -148,7 +148,7 @@
subsection {* Full function space is pointed *}
lemma minimal_fun: "(\<lambda>x. \<bottom>) \<sqsubseteq> f"
-by (simp add: less_fun_def)
+by (simp add: below_fun_def)
lemma least_fun: "\<exists>x::'a::type \<Rightarrow> 'b::pcpo. \<forall>y. x \<sqsubseteq> y"
apply (rule_tac x = "\<lambda>x. \<bottom>" in exI)
@@ -171,13 +171,13 @@
*}
lemma monofun_fun_fun: "f \<sqsubseteq> g \<Longrightarrow> f x \<sqsubseteq> g x"
-by (simp add: less_fun_def)
+by (simp add: below_fun_def)
lemma monofun_fun_arg: "\<lbrakk>monofun f; x \<sqsubseteq> y\<rbrakk> \<Longrightarrow> f x \<sqsubseteq> f y"
by (rule monofunE)
lemma monofun_fun: "\<lbrakk>monofun f; monofun g; f \<sqsubseteq> g; x \<sqsubseteq> y\<rbrakk> \<Longrightarrow> f x \<sqsubseteq> g y"
-by (rule trans_less [OF monofun_fun_arg monofun_fun_fun])
+by (rule below_trans [OF monofun_fun_arg monofun_fun_fun])
subsection {* Propagation of monotonicity and continuity *}
@@ -236,7 +236,7 @@
lemma mono2mono_lambda:
assumes f: "\<And>y. monofun (\<lambda>x. f x y)" shows "monofun f"
apply (rule monofunI)
-apply (rule less_fun_ext)
+apply (rule below_fun_ext)
apply (erule monofunE [OF f])
done
@@ -296,4 +296,3 @@
by (rule cont2cont_app2 [OF cont_const])
end
-
--- a/src/HOLCF/Fix.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Fix.thy Mon May 11 17:20:52 2009 +0200
@@ -90,7 +90,7 @@
apply simp
done
-lemma fix_least_less: "F\<cdot>x \<sqsubseteq> x \<Longrightarrow> fix\<cdot>F \<sqsubseteq> x"
+lemma fix_least_below: "F\<cdot>x \<sqsubseteq> x \<Longrightarrow> fix\<cdot>F \<sqsubseteq> x"
apply (simp add: fix_def2)
apply (rule is_lub_thelub)
apply (rule chain_iterate)
@@ -98,17 +98,17 @@
apply (induct_tac i)
apply simp
apply simp
-apply (erule rev_trans_less)
+apply (erule rev_below_trans)
apply (erule monofun_cfun_arg)
done
lemma fix_least: "F\<cdot>x = x \<Longrightarrow> fix\<cdot>F \<sqsubseteq> x"
-by (rule fix_least_less, simp)
+by (rule fix_least_below, simp)
lemma fix_eqI:
assumes fixed: "F\<cdot>x = x" and least: "\<And>z. F\<cdot>z = z \<Longrightarrow> x \<sqsubseteq> z"
shows "fix\<cdot>F = x"
-apply (rule antisym_less)
+apply (rule below_antisym)
apply (rule fix_least [OF fixed])
apply (rule least [OF fix_eq [symmetric]])
done
@@ -230,10 +230,10 @@
have "?y1 \<sqsubseteq> y" by (rule fix_least, simp add: F_y)
hence "cfst\<cdot>(F\<cdot>\<langle>x, ?y1\<rangle>) \<sqsubseteq> cfst\<cdot>(F\<cdot>\<langle>x, y\<rangle>)" by (simp add: monofun_cfun)
hence "cfst\<cdot>(F\<cdot>\<langle>x, ?y1\<rangle>) \<sqsubseteq> x" using F_x by simp
- hence 1: "?x \<sqsubseteq> x" by (simp add: fix_least_less)
+ hence 1: "?x \<sqsubseteq> x" by (simp add: fix_least_below)
hence "csnd\<cdot>(F\<cdot>\<langle>?x, y\<rangle>) \<sqsubseteq> csnd\<cdot>(F\<cdot>\<langle>x, y\<rangle>)" by (simp add: monofun_cfun)
hence "csnd\<cdot>(F\<cdot>\<langle>?x, y\<rangle>) \<sqsubseteq> y" using F_y by simp
- hence 2: "?y \<sqsubseteq> y" by (simp add: fix_least_less)
+ hence 2: "?y \<sqsubseteq> y" by (simp add: fix_least_below)
show "\<langle>?x, ?y\<rangle> \<sqsubseteq> z" using z 1 2 by simp
qed
--- a/src/HOLCF/Fixrec.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Fixrec.thy Mon May 11 17:20:52 2009 +0200
@@ -475,86 +475,96 @@
defaultsort pcpo
definition
- match_UU :: "'a \<rightarrow> unit maybe" where
- "match_UU = (\<Lambda> x. fail)"
+ match_UU :: "'a \<rightarrow> 'c maybe \<rightarrow> 'c maybe"
+where
+ "match_UU = strictify\<cdot>(\<Lambda> x k. fail)"
definition
- match_cpair :: "'a::cpo \<times> 'b::cpo \<rightarrow> ('a \<times> 'b) maybe" where
- "match_cpair = csplit\<cdot>(\<Lambda> x y. return\<cdot><x,y>)"
+ match_cpair :: "'a::cpo \<times> 'b::cpo \<rightarrow> ('a \<rightarrow> 'b \<rightarrow> 'c maybe) \<rightarrow> 'c maybe"
+where
+ "match_cpair = (\<Lambda> x k. csplit\<cdot>k\<cdot>x)"
definition
- match_spair :: "'a \<otimes> 'b \<rightarrow> ('a \<times> 'b) maybe" where
- "match_spair = ssplit\<cdot>(\<Lambda> x y. return\<cdot><x,y>)"
+ match_spair :: "'a \<otimes> 'b \<rightarrow> ('a \<rightarrow> 'b \<rightarrow> 'c maybe) \<rightarrow> 'c maybe"
+where
+ "match_spair = (\<Lambda> x k. ssplit\<cdot>k\<cdot>x)"
definition
- match_sinl :: "'a \<oplus> 'b \<rightarrow> 'a maybe" where
- "match_sinl = sscase\<cdot>return\<cdot>(\<Lambda> y. fail)"
+ match_sinl :: "'a \<oplus> 'b \<rightarrow> ('a \<rightarrow> 'c maybe) \<rightarrow> 'c maybe"
+where
+ "match_sinl = (\<Lambda> x k. sscase\<cdot>k\<cdot>(\<Lambda> b. fail)\<cdot>x)"
definition
- match_sinr :: "'a \<oplus> 'b \<rightarrow> 'b maybe" where
- "match_sinr = sscase\<cdot>(\<Lambda> x. fail)\<cdot>return"
+ match_sinr :: "'a \<oplus> 'b \<rightarrow> ('b \<rightarrow> 'c maybe) \<rightarrow> 'c maybe"
+where
+ "match_sinr = (\<Lambda> x k. sscase\<cdot>(\<Lambda> a. fail)\<cdot>k\<cdot>x)"
definition
- match_up :: "'a::cpo u \<rightarrow> 'a maybe" where
- "match_up = fup\<cdot>return"
+ match_up :: "'a::cpo u \<rightarrow> ('a \<rightarrow> 'c maybe) \<rightarrow> 'c maybe"
+where
+ "match_up = (\<Lambda> x k. fup\<cdot>k\<cdot>x)"
definition
- match_ONE :: "one \<rightarrow> unit maybe" where
- "match_ONE = (\<Lambda> ONE. return\<cdot>())"
+ match_ONE :: "one \<rightarrow> 'c maybe \<rightarrow> 'c maybe"
+where
+ "match_ONE = (\<Lambda> ONE k. k)"
+
+definition
+ match_TT :: "tr \<rightarrow> 'c maybe \<rightarrow> 'c maybe"
+where
+ "match_TT = (\<Lambda> x k. If x then k else fail fi)"
definition
- match_TT :: "tr \<rightarrow> unit maybe" where
- "match_TT = (\<Lambda> b. If b then return\<cdot>() else fail fi)"
-
-definition
- match_FF :: "tr \<rightarrow> unit maybe" where
- "match_FF = (\<Lambda> b. If b then fail else return\<cdot>() fi)"
+ match_FF :: "tr \<rightarrow> 'c maybe \<rightarrow> 'c maybe"
+where
+ "match_FF = (\<Lambda> x k. If x then fail else k fi)"
lemma match_UU_simps [simp]:
- "match_UU\<cdot>x = fail"
-by (simp add: match_UU_def)
+ "match_UU\<cdot>\<bottom>\<cdot>k = \<bottom>"
+ "x \<noteq> \<bottom> \<Longrightarrow> match_UU\<cdot>x\<cdot>k = fail"
+by (simp_all add: match_UU_def)
lemma match_cpair_simps [simp]:
- "match_cpair\<cdot><x,y> = return\<cdot><x,y>"
+ "match_cpair\<cdot>\<langle>x, y\<rangle>\<cdot>k = k\<cdot>x\<cdot>y"
by (simp add: match_cpair_def)
lemma match_spair_simps [simp]:
- "\<lbrakk>x \<noteq> \<bottom>; y \<noteq> \<bottom>\<rbrakk> \<Longrightarrow> match_spair\<cdot>(:x,y:) = return\<cdot><x,y>"
- "match_spair\<cdot>\<bottom> = \<bottom>"
+ "\<lbrakk>x \<noteq> \<bottom>; y \<noteq> \<bottom>\<rbrakk> \<Longrightarrow> match_spair\<cdot>(:x, y:)\<cdot>k = k\<cdot>x\<cdot>y"
+ "match_spair\<cdot>\<bottom>\<cdot>k = \<bottom>"
by (simp_all add: match_spair_def)
lemma match_sinl_simps [simp]:
- "x \<noteq> \<bottom> \<Longrightarrow> match_sinl\<cdot>(sinl\<cdot>x) = return\<cdot>x"
- "x \<noteq> \<bottom> \<Longrightarrow> match_sinl\<cdot>(sinr\<cdot>x) = fail"
- "match_sinl\<cdot>\<bottom> = \<bottom>"
+ "x \<noteq> \<bottom> \<Longrightarrow> match_sinl\<cdot>(sinl\<cdot>x)\<cdot>k = k\<cdot>x"
+ "y \<noteq> \<bottom> \<Longrightarrow> match_sinl\<cdot>(sinr\<cdot>y)\<cdot>k = fail"
+ "match_sinl\<cdot>\<bottom>\<cdot>k = \<bottom>"
by (simp_all add: match_sinl_def)
lemma match_sinr_simps [simp]:
- "x \<noteq> \<bottom> \<Longrightarrow> match_sinr\<cdot>(sinr\<cdot>x) = return\<cdot>x"
- "x \<noteq> \<bottom> \<Longrightarrow> match_sinr\<cdot>(sinl\<cdot>x) = fail"
- "match_sinr\<cdot>\<bottom> = \<bottom>"
+ "x \<noteq> \<bottom> \<Longrightarrow> match_sinr\<cdot>(sinl\<cdot>x)\<cdot>k = fail"
+ "y \<noteq> \<bottom> \<Longrightarrow> match_sinr\<cdot>(sinr\<cdot>y)\<cdot>k = k\<cdot>y"
+ "match_sinr\<cdot>\<bottom>\<cdot>k = \<bottom>"
by (simp_all add: match_sinr_def)
lemma match_up_simps [simp]:
- "match_up\<cdot>(up\<cdot>x) = return\<cdot>x"
- "match_up\<cdot>\<bottom> = \<bottom>"
+ "match_up\<cdot>(up\<cdot>x)\<cdot>k = k\<cdot>x"
+ "match_up\<cdot>\<bottom>\<cdot>k = \<bottom>"
by (simp_all add: match_up_def)
lemma match_ONE_simps [simp]:
- "match_ONE\<cdot>ONE = return\<cdot>()"
- "match_ONE\<cdot>\<bottom> = \<bottom>"
+ "match_ONE\<cdot>ONE\<cdot>k = k"
+ "match_ONE\<cdot>\<bottom>\<cdot>k = \<bottom>"
by (simp_all add: match_ONE_def)
lemma match_TT_simps [simp]:
- "match_TT\<cdot>TT = return\<cdot>()"
- "match_TT\<cdot>FF = fail"
- "match_TT\<cdot>\<bottom> = \<bottom>"
+ "match_TT\<cdot>TT\<cdot>k = k"
+ "match_TT\<cdot>FF\<cdot>k = fail"
+ "match_TT\<cdot>\<bottom>\<cdot>k = \<bottom>"
by (simp_all add: match_TT_def)
lemma match_FF_simps [simp]:
- "match_FF\<cdot>FF = return\<cdot>()"
- "match_FF\<cdot>TT = fail"
- "match_FF\<cdot>\<bottom> = \<bottom>"
+ "match_FF\<cdot>FF\<cdot>k = k"
+ "match_FF\<cdot>TT\<cdot>k = fail"
+ "match_FF\<cdot>\<bottom>\<cdot>k = \<bottom>"
by (simp_all add: match_FF_def)
subsection {* Mutual recursion *}
@@ -594,7 +604,8 @@
(@{const_name cpair}, @{const_name match_cpair}),
(@{const_name ONE}, @{const_name match_ONE}),
(@{const_name TT}, @{const_name match_TT}),
- (@{const_name FF}, @{const_name match_FF}) ]
+ (@{const_name FF}, @{const_name match_FF}),
+ (@{const_name UU}, @{const_name match_UU}) ]
*}
hide (open) const return bind fail run cases
--- a/src/HOLCF/HOLCF.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/HOLCF.thy Mon May 11 17:20:52 2009 +0200
@@ -9,13 +9,6 @@
Domain ConvexPD Algebraic Universal Sum_Cpo Main
uses
"holcf_logic.ML"
- "Tools/cont_consts.ML"
- "Tools/cont_proc.ML"
- "Tools/domain/domain_library.ML"
- "Tools/domain/domain_syntax.ML"
- "Tools/domain/domain_axioms.ML"
- "Tools/domain/domain_theorems.ML"
- "Tools/domain/domain_extender.ML"
"Tools/adm_tac.ML"
begin
@@ -28,4 +21,58 @@
(cut_facts_tac (Simplifier.prems_of_ss ss) THEN' cont_tacRs ss))));
*}
+text {* Legacy theorem names *}
+
+lemmas sq_ord_less_eq_trans = below_eq_trans
+lemmas sq_ord_eq_less_trans = eq_below_trans
+lemmas refl_less = below_refl
+lemmas trans_less = below_trans
+lemmas antisym_less = below_antisym
+lemmas antisym_less_inverse = below_antisym_inverse
+lemmas box_less = box_below
+lemmas rev_trans_less = rev_below_trans
+lemmas not_less2not_eq = not_below2not_eq
+lemmas less_UU_iff = below_UU_iff
+lemmas flat_less_iff = flat_below_iff
+lemmas adm_less = adm_below
+lemmas adm_not_less = adm_not_below
+lemmas adm_compact_not_less = adm_compact_not_below
+lemmas less_fun_def = below_fun_def
+lemmas expand_fun_less = expand_fun_below
+lemmas less_fun_ext = below_fun_ext
+lemmas less_discr_def = below_discr_def
+lemmas discr_less_eq = discr_below_eq
+lemmas less_unit_def = below_unit_def
+lemmas less_cprod_def = below_prod_def
+lemmas prod_lessI = prod_belowI
+lemmas Pair_less_iff = Pair_below_iff
+lemmas fst_less_iff = fst_below_iff
+lemmas snd_less_iff = snd_below_iff
+lemmas expand_cfun_less = expand_cfun_below
+lemmas less_cfun_ext = below_cfun_ext
+lemmas injection_less = injection_below
+lemmas approx_less = approx_below
+lemmas profinite_less_ext = profinite_below_ext
+lemmas less_up_def = below_up_def
+lemmas not_Iup_less = not_Iup_below
+lemmas Iup_less = Iup_below
+lemmas up_less = up_below
+lemmas cpair_less = cpair_below
+lemmas less_cprod = below_cprod
+lemmas cfst_less_iff = cfst_below_iff
+lemmas csnd_less_iff = csnd_below_iff
+lemmas Def_inject_less_eq = Def_below_Def
+lemmas Def_less_is_eq = Def_below_iff
+lemmas spair_less_iff = spair_below_iff
+lemmas less_sprod = below_sprod
+lemmas spair_less = spair_below
+lemmas sfst_less_iff = sfst_below_iff
+lemmas ssnd_less_iff = ssnd_below_iff
+lemmas fix_least_less = fix_least_below
+lemmas dist_less_one = dist_below_one
+lemmas less_ONE = below_ONE
+lemmas ONE_less_iff = ONE_below_iff
+lemmas less_sinlD = below_sinlD
+lemmas less_sinrD = below_sinrD
+
end
--- a/src/HOLCF/IOA/meta_theory/Sequence.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/IOA/meta_theory/Sequence.thy Mon May 11 17:20:52 2009 +0200
@@ -288,8 +288,7 @@
lemma Cons_not_UU: "a>>s ~= UU"
apply (subst Consq_def2)
-apply (rule seq.con_rews)
-apply (rule Def_not_UU)
+apply simp
done
--- a/src/HOLCF/IOA/meta_theory/ioa_package.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/IOA/meta_theory/ioa_package.ML Mon May 11 17:20:52 2009 +0200
@@ -347,12 +347,12 @@
val alt_string = make_alt_string thy inp_head_list out_head_list int_head_list
atyp statetupel trans;
val thy2 = (thy
-|> ContConsts.add_consts
-[(automaton_name ^ "_initial", "(" ^ state_type_string ^ ")set" ,NoSyn),
-(automaton_name ^ "_asig", "(" ^ action_type ^ ")signature" ,NoSyn),
-(automaton_name ^ "_trans",
+|> Sign.add_consts
+[(Binding.name (automaton_name ^ "_initial"), "(" ^ state_type_string ^ ")set" ,NoSyn),
+(Binding.name (automaton_name ^ "_asig"), "(" ^ action_type ^ ")signature" ,NoSyn),
+(Binding.name (automaton_name ^ "_trans"),
"(" ^ action_type ^ "," ^ state_type_string ^ ")transition set" ,NoSyn),
-(automaton_name, "(" ^ action_type ^ "," ^ state_type_string ^ ")ioa" ,NoSyn)]
+(Binding.name automaton_name, "(" ^ action_type ^ "," ^ state_type_string ^ ")ioa" ,NoSyn)]
|> add_defs
[(automaton_name ^ "_initial_def",
automaton_name ^ "_initial == {" ^ state_vars_tupel ^ "." ^ ini ^ "}"),
@@ -386,8 +386,8 @@
val comp_list = clist aut_list;
in
thy
-|> ContConsts.add_consts_i
-[(automaton_name,
+|> Sign.add_consts_i
+[(Binding.name automaton_name,
Type("*",
[Type("*",[Type("set",[acttyp]),Type("*",[Type("set",[acttyp]),Type("set",[acttyp])])]),
Type("*",[Type("set",[st_typ]),
@@ -407,8 +407,8 @@
val rest_set = action_set_string thy acttyp actlist
in
thy
-|> ContConsts.add_consts_i
-[(automaton_name, auttyp,NoSyn)]
+|> Sign.add_consts_i
+[(Binding.name automaton_name, auttyp,NoSyn)]
|> add_defs
[(automaton_name ^ "_def",
automaton_name ^ " == restrict " ^ aut_source ^ " " ^ rest_set)]
@@ -421,8 +421,8 @@
val hid_set = action_set_string thy acttyp actlist
in
thy
-|> ContConsts.add_consts_i
-[(automaton_name, auttyp,NoSyn)]
+|> Sign.add_consts_i
+[(Binding.name automaton_name, auttyp,NoSyn)]
|> add_defs
[(automaton_name ^ "_def",
automaton_name ^ " == hide " ^ aut_source ^ " " ^ hid_set)]
@@ -441,8 +441,8 @@
val acttyp = ren_act_type_of thy fun_name
in
thy
-|> ContConsts.add_consts_i
-[(automaton_name,
+|> Sign.add_consts_i
+[(Binding.name automaton_name,
Type("*",
[Type("*",[Type("set",[acttyp]),Type("*",[Type("set",[acttyp]),Type("set",[acttyp])])]),
Type("*",[Type("set",[st_typ]),
--- a/src/HOLCF/IsaMakefile Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/IsaMakefile Mon May 11 17:20:52 2009 +0200
@@ -87,10 +87,19 @@
HOLCF-ex: HOLCF $(LOG)/HOLCF-ex.gz
-$(LOG)/HOLCF-ex.gz: $(OUT)/HOLCF ex/Stream.thy ex/Dagstuhl.thy \
- ex/Dnat.thy ex/Fix2.thy ex/Focus_ex.thy ex/Hoare.thy ex/Loop.thy \
+$(LOG)/HOLCF-ex.gz: $(OUT)/HOLCF \
+ ../HOL/Library/Nat_Infinity.thy \
+ ex/Dagstuhl.thy \
+ ex/Dnat.thy \
+ ex/Domain_ex.thy \
+ ex/Fix2.thy \
+ ex/Fixrec_ex.thy \
+ ex/Focus_ex.thy \
+ ex/Hoare.thy \
+ ex/Loop.thy \
ex/Powerdomain_ex.thy \
- ex/ROOT.ML ex/Fixrec_ex.thy ../HOL/Library/Nat_Infinity.thy
+ ex/Stream.thy \
+ ex/ROOT.ML
@$(ISABELLE_TOOL) usedir $(OUT)/HOLCF ex
--- a/src/HOLCF/Lift.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Lift.thy Mon May 11 17:20:52 2009 +0200
@@ -70,11 +70,11 @@
lemma DefE2: "\<lbrakk>x = Def s; x = \<bottom>\<rbrakk> \<Longrightarrow> R"
by simp
-lemma Def_inject_less_eq: "Def x \<sqsubseteq> Def y \<longleftrightarrow> x = y"
-by (simp add: less_lift_def Def_def Abs_lift_inverse lift_def)
+lemma Def_below_Def: "Def x \<sqsubseteq> Def y \<longleftrightarrow> x = y"
+by (simp add: below_lift_def Def_def Abs_lift_inverse lift_def)
-lemma Def_less_is_eq [simp]: "Def x \<sqsubseteq> y \<longleftrightarrow> Def x = y"
-by (induct y, simp, simp add: Def_inject_less_eq)
+lemma Def_below_iff [simp]: "Def x \<sqsubseteq> y \<longleftrightarrow> Def x = y"
+by (induct y, simp, simp add: Def_below_Def)
subsection {* Lift is flat *}
@@ -134,7 +134,7 @@
"(\<And>x. f x \<sqsubseteq> g x) \<Longrightarrow> (FLIFT x. f x) \<sqsubseteq> (FLIFT x. g x)"
apply (rule monofunE [where f=flift1])
apply (rule cont2mono [OF cont_flift1])
-apply (simp add: less_fun_ext)
+apply (simp add: below_fun_ext)
done
lemma cont2cont_flift1 [simp]:
@@ -216,7 +216,7 @@
apply (rule is_lubI)
apply (rule ub_rangeI, simp)
apply (drule ub_rangeD)
- apply (erule rev_trans_less)
+ apply (erule rev_below_trans)
apply simp
apply (rule lessI)
done
--- a/src/HOLCF/LowerPD.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/LowerPD.thy Mon May 11 17:20:52 2009 +0200
@@ -23,7 +23,7 @@
apply (drule (1) bspec, erule bexE)
apply (drule (1) bspec, erule bexE)
apply (erule rev_bexI)
-apply (erule (1) trans_less)
+apply (erule (1) below_trans)
done
interpretation lower_le: preorder lower_le
@@ -39,7 +39,7 @@
lemma PDPlus_lower_mono: "\<lbrakk>s \<le>\<flat> t; u \<le>\<flat> v\<rbrakk> \<Longrightarrow> PDPlus s u \<le>\<flat> PDPlus t v"
unfolding lower_le_def Rep_PDPlus by fast
-lemma PDPlus_lower_less: "t \<le>\<flat> PDPlus t u"
+lemma PDPlus_lower_le: "t \<le>\<flat> PDPlus t u"
unfolding lower_le_def Rep_PDPlus by fast
lemma lower_le_PDUnit_PDUnit_iff [simp]:
@@ -99,7 +99,7 @@
"{S::'a pd_basis set. lower_le.ideal S}"
by (fast intro: lower_le.ideal_principal)
-instantiation lower_pd :: (profinite) sq_ord
+instantiation lower_pd :: (profinite) below
begin
definition
@@ -110,16 +110,16 @@
instance lower_pd :: (profinite) po
by (rule lower_le.typedef_ideal_po
- [OF type_definition_lower_pd sq_le_lower_pd_def])
+ [OF type_definition_lower_pd below_lower_pd_def])
instance lower_pd :: (profinite) cpo
by (rule lower_le.typedef_ideal_cpo
- [OF type_definition_lower_pd sq_le_lower_pd_def])
+ [OF type_definition_lower_pd below_lower_pd_def])
lemma Rep_lower_pd_lub:
"chain Y \<Longrightarrow> Rep_lower_pd (\<Squnion>i. Y i) = (\<Union>i. Rep_lower_pd (Y i))"
by (rule lower_le.typedef_ideal_rep_contlub
- [OF type_definition_lower_pd sq_le_lower_pd_def])
+ [OF type_definition_lower_pd below_lower_pd_def])
lemma ideal_Rep_lower_pd: "lower_le.ideal (Rep_lower_pd xs)"
by (rule Rep_lower_pd [unfolded mem_Collect_eq])
@@ -145,7 +145,7 @@
apply (rule ideal_Rep_lower_pd)
apply (erule Rep_lower_pd_lub)
apply (rule Rep_lower_principal)
-apply (simp only: sq_le_lower_pd_def)
+apply (simp only: below_lower_pd_def)
done
text {* Lower powerdomain is pointed *}
@@ -264,28 +264,28 @@
lemmas lower_plus_aci =
lower_plus_ac lower_plus_absorb lower_plus_left_absorb
-lemma lower_plus_less1: "xs \<sqsubseteq> xs +\<flat> ys"
+lemma lower_plus_below1: "xs \<sqsubseteq> xs +\<flat> ys"
apply (induct xs ys rule: lower_pd.principal_induct2, simp, simp)
-apply (simp add: PDPlus_lower_less)
+apply (simp add: PDPlus_lower_le)
done
-lemma lower_plus_less2: "ys \<sqsubseteq> xs +\<flat> ys"
-by (subst lower_plus_commute, rule lower_plus_less1)
+lemma lower_plus_below2: "ys \<sqsubseteq> xs +\<flat> ys"
+by (subst lower_plus_commute, rule lower_plus_below1)
lemma lower_plus_least: "\<lbrakk>xs \<sqsubseteq> zs; ys \<sqsubseteq> zs\<rbrakk> \<Longrightarrow> xs +\<flat> ys \<sqsubseteq> zs"
apply (subst lower_plus_absorb [of zs, symmetric])
apply (erule (1) monofun_cfun [OF monofun_cfun_arg])
done
-lemma lower_plus_less_iff:
+lemma lower_plus_below_iff:
"xs +\<flat> ys \<sqsubseteq> zs \<longleftrightarrow> xs \<sqsubseteq> zs \<and> ys \<sqsubseteq> zs"
apply safe
-apply (erule trans_less [OF lower_plus_less1])
-apply (erule trans_less [OF lower_plus_less2])
+apply (erule below_trans [OF lower_plus_below1])
+apply (erule below_trans [OF lower_plus_below2])
apply (erule (1) lower_plus_least)
done
-lemma lower_unit_less_plus_iff:
+lemma lower_unit_below_plus_iff:
"{x}\<flat> \<sqsubseteq> ys +\<flat> zs \<longleftrightarrow> {x}\<flat> \<sqsubseteq> ys \<or> {x}\<flat> \<sqsubseteq> zs"
apply (rule iffI)
apply (subgoal_tac
@@ -299,13 +299,13 @@
apply simp
apply simp
apply (erule disjE)
- apply (erule trans_less [OF _ lower_plus_less1])
- apply (erule trans_less [OF _ lower_plus_less2])
+ apply (erule below_trans [OF _ lower_plus_below1])
+ apply (erule below_trans [OF _ lower_plus_below2])
done
-lemma lower_unit_less_iff [simp]: "{x}\<flat> \<sqsubseteq> {y}\<flat> \<longleftrightarrow> x \<sqsubseteq> y"
+lemma lower_unit_below_iff [simp]: "{x}\<flat> \<sqsubseteq> {y}\<flat> \<longleftrightarrow> x \<sqsubseteq> y"
apply (rule iffI)
- apply (rule profinite_less_ext)
+ apply (rule profinite_below_ext)
apply (drule_tac f="approx i" in monofun_cfun_arg, simp)
apply (cut_tac x="approx i\<cdot>x" in compact_basis.compact_imp_principal, simp)
apply (cut_tac x="approx i\<cdot>y" in compact_basis.compact_imp_principal, simp)
@@ -313,10 +313,10 @@
apply (erule monofun_cfun_arg)
done
-lemmas lower_pd_less_simps =
- lower_unit_less_iff
- lower_plus_less_iff
- lower_unit_less_plus_iff
+lemmas lower_pd_below_simps =
+ lower_unit_below_iff
+ lower_plus_below_iff
+ lower_unit_below_plus_iff
lemma lower_unit_eq_iff [simp]: "{x}\<flat> = {y}\<flat> \<longleftrightarrow> x = y"
by (simp add: po_eq_conv)
@@ -330,18 +330,18 @@
lemma lower_plus_strict_iff [simp]:
"xs +\<flat> ys = \<bottom> \<longleftrightarrow> xs = \<bottom> \<and> ys = \<bottom>"
apply safe
-apply (rule UU_I, erule subst, rule lower_plus_less1)
-apply (rule UU_I, erule subst, rule lower_plus_less2)
+apply (rule UU_I, erule subst, rule lower_plus_below1)
+apply (rule UU_I, erule subst, rule lower_plus_below2)
apply (rule lower_plus_absorb)
done
lemma lower_plus_strict1 [simp]: "\<bottom> +\<flat> ys = ys"
-apply (rule antisym_less [OF _ lower_plus_less2])
+apply (rule below_antisym [OF _ lower_plus_below2])
apply (simp add: lower_plus_least)
done
lemma lower_plus_strict2 [simp]: "xs +\<flat> \<bottom> = xs"
-apply (rule antisym_less [OF _ lower_plus_less1])
+apply (rule below_antisym [OF _ lower_plus_below1])
apply (simp add: lower_plus_least)
done
@@ -412,11 +412,11 @@
lemma lower_bind_basis_mono:
"t \<le>\<flat> u \<Longrightarrow> lower_bind_basis t \<sqsubseteq> lower_bind_basis u"
-unfolding expand_cfun_less
+unfolding expand_cfun_below
apply (erule lower_le_induct, safe)
apply (simp add: monofun_cfun)
-apply (simp add: rev_trans_less [OF lower_plus_less1])
-apply (simp add: lower_plus_less_iff)
+apply (simp add: rev_below_trans [OF lower_plus_below1])
+apply (simp add: lower_plus_below_iff)
done
definition
--- a/src/HOLCF/One.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/One.thy Mon May 11 17:20:52 2009 +0200
@@ -28,17 +28,17 @@
lemma one_induct: "\<lbrakk>P \<bottom>; P ONE\<rbrakk> \<Longrightarrow> P x"
by (cases x rule: oneE) simp_all
-lemma dist_less_one [simp]: "\<not> ONE \<sqsubseteq> \<bottom>"
+lemma dist_below_one [simp]: "\<not> ONE \<sqsubseteq> \<bottom>"
unfolding ONE_def by simp
-lemma less_ONE [simp]: "x \<sqsubseteq> ONE"
+lemma below_ONE [simp]: "x \<sqsubseteq> ONE"
by (induct x rule: one_induct) simp_all
-lemma ONE_less_iff [simp]: "ONE \<sqsubseteq> x \<longleftrightarrow> x = ONE"
+lemma ONE_below_iff [simp]: "ONE \<sqsubseteq> x \<longleftrightarrow> x = ONE"
by (induct x rule: one_induct) simp_all
-lemma dist_eq_one [simp]: "ONE \<noteq> \<bottom>" "\<bottom> \<noteq> ONE"
-unfolding ONE_def by simp_all
+lemma ONE_defined [simp]: "ONE \<noteq> \<bottom>"
+unfolding ONE_def by simp
lemma one_neq_iffs [simp]:
"x \<noteq> ONE \<longleftrightarrow> x = \<bottom>"
--- a/src/HOLCF/Pcpo.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Pcpo.thy Mon May 11 17:20:52 2009 +0200
@@ -13,28 +13,28 @@
text {* The class cpo of chain complete partial orders *}
class cpo = po +
- -- {* class axiom: *}
- assumes cpo: "chain S \<Longrightarrow> \<exists>x :: 'a::po. range S <<| x"
+ assumes cpo: "chain S \<Longrightarrow> \<exists>x. range S <<| x"
+begin
text {* in cpo's everthing equal to THE lub has lub properties for every chain *}
-lemma cpo_lubI: "chain (S::nat \<Rightarrow> 'a::cpo) \<Longrightarrow> range S <<| (\<Squnion>i. S i)"
-by (fast dest: cpo elim: lubI)
+lemma cpo_lubI: "chain S \<Longrightarrow> range S <<| (\<Squnion>i. S i)"
+ by (fast dest: cpo elim: lubI)
-lemma thelubE: "\<lbrakk>chain S; (\<Squnion>i. S i) = (l::'a::cpo)\<rbrakk> \<Longrightarrow> range S <<| l"
-by (blast dest: cpo intro: lubI)
+lemma thelubE: "\<lbrakk>chain S; (\<Squnion>i. S i) = l\<rbrakk> \<Longrightarrow> range S <<| l"
+ by (blast dest: cpo intro: lubI)
text {* Properties of the lub *}
-lemma is_ub_thelub: "chain (S::nat \<Rightarrow> 'a::cpo) \<Longrightarrow> S x \<sqsubseteq> (\<Squnion>i. S i)"
-by (blast dest: cpo intro: lubI [THEN is_ub_lub])
+lemma is_ub_thelub: "chain S \<Longrightarrow> S x \<sqsubseteq> (\<Squnion>i. S i)"
+ by (blast dest: cpo intro: lubI [THEN is_ub_lub])
lemma is_lub_thelub:
- "\<lbrakk>chain (S::nat \<Rightarrow> 'a::cpo); range S <| x\<rbrakk> \<Longrightarrow> (\<Squnion>i. S i) \<sqsubseteq> x"
-by (blast dest: cpo intro: lubI [THEN is_lub_lub])
+ "\<lbrakk>chain S; range S <| x\<rbrakk> \<Longrightarrow> (\<Squnion>i. S i) \<sqsubseteq> x"
+ by (blast dest: cpo intro: lubI [THEN is_lub_lub])
lemma lub_range_mono:
- "\<lbrakk>range X \<subseteq> range Y; chain Y; chain (X::nat \<Rightarrow> 'a::cpo)\<rbrakk>
+ "\<lbrakk>range X \<subseteq> range Y; chain Y; chain X\<rbrakk>
\<Longrightarrow> (\<Squnion>i. X i) \<sqsubseteq> (\<Squnion>i. Y i)"
apply (erule is_lub_thelub)
apply (rule ub_rangeI)
@@ -45,8 +45,8 @@
done
lemma lub_range_shift:
- "chain (Y::nat \<Rightarrow> 'a::cpo) \<Longrightarrow> (\<Squnion>i. Y (i + j)) = (\<Squnion>i. Y i)"
-apply (rule antisym_less)
+ "chain Y \<Longrightarrow> (\<Squnion>i. Y (i + j)) = (\<Squnion>i. Y i)"
+apply (rule below_antisym)
apply (rule lub_range_mono)
apply fast
apply assumption
@@ -54,7 +54,7 @@
apply (rule is_lub_thelub)
apply assumption
apply (rule ub_rangeI)
-apply (rule_tac y="Y (i + j)" in trans_less)
+apply (rule_tac y="Y (i + j)" in below_trans)
apply (erule chain_mono)
apply (rule le_add1)
apply (rule is_ub_thelub)
@@ -62,11 +62,11 @@
done
lemma maxinch_is_thelub:
- "chain Y \<Longrightarrow> max_in_chain i Y = ((\<Squnion>i. Y i) = ((Y i)::'a::cpo))"
+ "chain Y \<Longrightarrow> max_in_chain i Y = ((\<Squnion>i. Y i) = Y i)"
apply (rule iffI)
apply (fast intro!: thelubI lub_finch1)
apply (unfold max_in_chain_def)
-apply (safe intro!: antisym_less)
+apply (safe intro!: below_antisym)
apply (fast elim!: chain_mono)
apply (drule sym)
apply (force elim!: is_ub_thelub)
@@ -75,11 +75,11 @@
text {* the @{text "\<sqsubseteq>"} relation between two chains is preserved by their lubs *}
lemma lub_mono:
- "\<lbrakk>chain (X::nat \<Rightarrow> 'a::cpo); chain Y; \<And>i. X i \<sqsubseteq> Y i\<rbrakk>
+ "\<lbrakk>chain X; chain Y; \<And>i. X i \<sqsubseteq> Y i\<rbrakk>
\<Longrightarrow> (\<Squnion>i. X i) \<sqsubseteq> (\<Squnion>i. Y i)"
apply (erule is_lub_thelub)
apply (rule ub_rangeI)
-apply (rule trans_less)
+apply (rule below_trans)
apply (erule meta_spec)
apply (erule is_ub_thelub)
done
@@ -87,14 +87,14 @@
text {* the = relation between two chains is preserved by their lubs *}
lemma lub_equal:
- "\<lbrakk>chain (X::nat \<Rightarrow> 'a::cpo); chain Y; \<forall>k. X k = Y k\<rbrakk>
+ "\<lbrakk>chain X; chain Y; \<forall>k. X k = Y k\<rbrakk>
\<Longrightarrow> (\<Squnion>i. X i) = (\<Squnion>i. Y i)"
-by (simp only: expand_fun_eq [symmetric])
+ by (simp only: expand_fun_eq [symmetric])
text {* more results about mono and = of lubs of chains *}
lemma lub_mono2:
- "\<lbrakk>\<exists>j. \<forall>i>j. X i = Y i; chain (X::nat \<Rightarrow> 'a::cpo); chain Y\<rbrakk>
+ "\<lbrakk>\<exists>j. \<forall>i>j. X i = Y i; chain X; chain Y\<rbrakk>
\<Longrightarrow> (\<Squnion>i. X i) \<sqsubseteq> (\<Squnion>i. Y i)"
apply (erule exE)
apply (subgoal_tac "(\<Squnion>i. X (i + Suc j)) \<sqsubseteq> (\<Squnion>i. Y (i + Suc j))")
@@ -104,23 +104,22 @@
done
lemma lub_equal2:
- "\<lbrakk>\<exists>j. \<forall>i>j. X i = Y i; chain (X::nat \<Rightarrow> 'a::cpo); chain Y\<rbrakk>
+ "\<lbrakk>\<exists>j. \<forall>i>j. X i = Y i; chain X; chain Y\<rbrakk>
\<Longrightarrow> (\<Squnion>i. X i) = (\<Squnion>i. Y i)"
-by (blast intro: antisym_less lub_mono2 sym)
+ by (blast intro: below_antisym lub_mono2 sym)
lemma lub_mono3:
- "\<lbrakk>chain (Y::nat \<Rightarrow> 'a::cpo); chain X; \<forall>i. \<exists>j. Y i \<sqsubseteq> X j\<rbrakk>
+ "\<lbrakk>chain Y; chain X; \<forall>i. \<exists>j. Y i \<sqsubseteq> X j\<rbrakk>
\<Longrightarrow> (\<Squnion>i. Y i) \<sqsubseteq> (\<Squnion>i. X i)"
apply (erule is_lub_thelub)
apply (rule ub_rangeI)
apply (erule allE)
apply (erule exE)
-apply (erule trans_less)
+apply (erule below_trans)
apply (erule is_ub_thelub)
done
lemma ch2ch_lub:
- fixes Y :: "nat \<Rightarrow> nat \<Rightarrow> 'a::cpo"
assumes 1: "\<And>j. chain (\<lambda>i. Y i j)"
assumes 2: "\<And>i. chain (\<lambda>j. Y i j)"
shows "chain (\<lambda>i. \<Squnion>j. Y i j)"
@@ -130,14 +129,13 @@
done
lemma diag_lub:
- fixes Y :: "nat \<Rightarrow> nat \<Rightarrow> 'a::cpo"
assumes 1: "\<And>j. chain (\<lambda>i. Y i j)"
assumes 2: "\<And>i. chain (\<lambda>j. Y i j)"
shows "(\<Squnion>i. \<Squnion>j. Y i j) = (\<Squnion>i. Y i i)"
-proof (rule antisym_less)
+proof (rule below_antisym)
have 3: "chain (\<lambda>i. Y i i)"
apply (rule chainI)
- apply (rule trans_less)
+ apply (rule below_trans)
apply (rule chainE [OF 1])
apply (rule chainE [OF 2])
done
@@ -148,7 +146,7 @@
apply (rule ub_rangeI)
apply (rule lub_mono3 [rule_format, OF 2 3])
apply (rule exI)
- apply (rule trans_less)
+ apply (rule below_trans)
apply (rule chain_mono [OF 1 le_maxI1])
apply (rule chain_mono [OF 2 le_maxI2])
done
@@ -159,12 +157,12 @@
qed
lemma ex_lub:
- fixes Y :: "nat \<Rightarrow> nat \<Rightarrow> 'a::cpo"
assumes 1: "\<And>j. chain (\<lambda>i. Y i j)"
assumes 2: "\<And>i. chain (\<lambda>j. Y i j)"
shows "(\<Squnion>i. \<Squnion>j. Y i j) = (\<Squnion>j. \<Squnion>i. Y i j)"
-by (simp add: diag_lub 1 2)
+ by (simp add: diag_lub 1 2)
+end
subsection {* Pointed cpos *}
@@ -172,9 +170,9 @@
class pcpo = cpo +
assumes least: "\<exists>x. \<forall>y. x \<sqsubseteq> y"
+begin
-definition
- UU :: "'a::pcpo" where
+definition UU :: 'a where
"UU = (THE x. \<forall>y. x \<sqsubseteq> y)"
notation (xsymbols)
@@ -187,36 +185,29 @@
apply (rule theI')
apply (rule ex_ex1I)
apply (rule least)
-apply (blast intro: antisym_less)
+apply (blast intro: below_antisym)
done
lemma minimal [iff]: "\<bottom> \<sqsubseteq> x"
by (rule UU_least [THEN spec])
-lemma UU_reorient: "(\<bottom> = x) = (x = \<bottom>)"
-by auto
+end
+
+text {* Simproc to rewrite @{term "\<bottom> = x"} to @{term "x = \<bottom>"}. *}
-ML {*
-local
- val meta_UU_reorient = thm "UU_reorient" RS eq_reflection;
- fun reorient_proc sg _ (_ $ t $ u) =
- case u of
- Const("Pcpo.UU",_) => NONE
- | Const("HOL.zero", _) => NONE
- | Const("HOL.one", _) => NONE
- | Const("Numeral.number_of", _) $ _ => NONE
- | _ => SOME meta_UU_reorient;
-in
- val UU_reorient_simproc =
- Simplifier.simproc (the_context ()) "UU_reorient_simproc" ["UU=x"] reorient_proc
-end;
+setup {*
+ ReorientProc.add
+ (fn Const(@{const_name UU}, _) => true | _ => false)
+*}
-Addsimprocs [UU_reorient_simproc];
-*}
+simproc_setup reorient_bottom ("\<bottom> = x") = ReorientProc.proc
+
+context pcpo
+begin
text {* useful lemmas about @{term \<bottom>} *}
-lemma less_UU_iff [simp]: "(x \<sqsubseteq> \<bottom>) = (x = \<bottom>)"
+lemma below_UU_iff [simp]: "(x \<sqsubseteq> \<bottom>) = (x = \<bottom>)"
by (simp add: po_eq_conv)
lemma eq_UU_iff: "(x = \<bottom>) = (x \<sqsubseteq> \<bottom>)"
@@ -225,9 +216,6 @@
lemma UU_I: "x \<sqsubseteq> \<bottom> \<Longrightarrow> x = \<bottom>"
by (subst eq_UU_iff)
-lemma not_less2not_eq: "\<not> (x::'a::po) \<sqsubseteq> y \<Longrightarrow> x \<noteq> y"
-by auto
-
lemma chain_UU_I: "\<lbrakk>chain Y; (\<Squnion>i. Y i) = \<bottom>\<rbrakk> \<Longrightarrow> \<forall>i. Y i = \<bottom>"
apply (rule allI)
apply (rule UU_I)
@@ -242,49 +230,53 @@
done
lemma chain_UU_I_inverse2: "(\<Squnion>i. Y i) \<noteq> \<bottom> \<Longrightarrow> \<exists>i::nat. Y i \<noteq> \<bottom>"
-by (blast intro: chain_UU_I_inverse)
+ by (blast intro: chain_UU_I_inverse)
lemma notUU_I: "\<lbrakk>x \<sqsubseteq> y; x \<noteq> \<bottom>\<rbrakk> \<Longrightarrow> y \<noteq> \<bottom>"
-by (blast intro: UU_I)
+ by (blast intro: UU_I)
lemma chain_mono2: "\<lbrakk>\<exists>j. Y j \<noteq> \<bottom>; chain Y\<rbrakk> \<Longrightarrow> \<exists>j. \<forall>i>j. Y i \<noteq> \<bottom>"
-by (blast dest: notUU_I chain_mono_less)
+ by (blast dest: notUU_I chain_mono_less)
+
+end
subsection {* Chain-finite and flat cpos *}
text {* further useful classes for HOLCF domains *}
-class finite_po = finite + po
+class chfin = po +
+ assumes chfin: "chain Y \<Longrightarrow> \<exists>n. max_in_chain n Y"
+begin
-class chfin = po +
- assumes chfin: "chain Y \<Longrightarrow> \<exists>n. max_in_chain n (Y :: nat => 'a::po)"
+subclass cpo
+apply default
+apply (frule chfin)
+apply (blast intro: lub_finch1)
+done
-class flat = pcpo +
- assumes ax_flat: "(x :: 'a::pcpo) \<sqsubseteq> y \<Longrightarrow> x = \<bottom> \<or> x = y"
+lemma chfin2finch: "chain Y \<Longrightarrow> finite_chain Y"
+ by (simp add: chfin finite_chain_def)
+
+end
-text {* finite partial orders are chain-finite *}
+class finite_po = finite + po
+begin
-instance finite_po < chfin
-apply intro_classes
+subclass chfin
+apply default
apply (drule finite_range_imp_finch)
apply (rule finite)
apply (simp add: finite_chain_def)
done
-text {* some properties for chfin and flat *}
-
-text {* chfin types are cpo *}
+end
-instance chfin < cpo
-apply intro_classes
-apply (frule chfin)
-apply (blast intro: lub_finch1)
-done
+class flat = pcpo +
+ assumes ax_flat: "x \<sqsubseteq> y \<Longrightarrow> x = \<bottom> \<or> x = y"
+begin
-text {* flat types are chfin *}
-
-instance flat < chfin
-apply intro_classes
+subclass chfin
+apply default
apply (unfold max_in_chain_def)
apply (case_tac "\<forall>i. Y i = \<bottom>")
apply simp
@@ -295,31 +287,28 @@
apply (blast dest: chain_mono ax_flat)
done
-text {* flat subclass of chfin; @{text adm_flat} not needed *}
-
-lemma flat_less_iff:
- fixes x y :: "'a::flat"
+lemma flat_below_iff:
shows "(x \<sqsubseteq> y) = (x = \<bottom> \<or> x = y)"
-by (safe dest!: ax_flat)
+ by (safe dest!: ax_flat)
-lemma flat_eq: "(a::'a::flat) \<noteq> \<bottom> \<Longrightarrow> a \<sqsubseteq> b = (a = b)"
-by (safe dest!: ax_flat)
+lemma flat_eq: "a \<noteq> \<bottom> \<Longrightarrow> a \<sqsubseteq> b = (a = b)"
+ by (safe dest!: ax_flat)
-lemma chfin2finch: "chain (Y::nat \<Rightarrow> 'a::chfin) \<Longrightarrow> finite_chain Y"
-by (simp add: chfin finite_chain_def)
+end
text {* Discrete cpos *}
-class discrete_cpo = sq_ord +
+class discrete_cpo = below +
assumes discrete_cpo [simp]: "x \<sqsubseteq> y \<longleftrightarrow> x = y"
+begin
-subclass (in discrete_cpo) po
+subclass po
proof qed simp_all
text {* In a discrete cpo, every chain is constant *}
lemma discrete_chain_const:
- assumes S: "chain (S::nat \<Rightarrow> 'a::discrete_cpo)"
+ assumes S: "chain S"
shows "\<exists>x. S = (\<lambda>i. x)"
proof (intro exI ext)
fix i :: nat
@@ -328,7 +317,7 @@
thus "S i = S 0" by (rule sym)
qed
-instance discrete_cpo < cpo
+subclass cpo
proof
fix S :: "nat \<Rightarrow> 'a"
assume S: "chain S"
@@ -338,31 +327,6 @@
by (fast intro: lub_const)
qed
-text {* lemmata for improved admissibility introdution rule *}
-
-lemma infinite_chain_adm_lemma:
- "\<lbrakk>chain Y; \<forall>i. P (Y i);
- \<And>Y. \<lbrakk>chain Y; \<forall>i. P (Y i); \<not> finite_chain Y\<rbrakk> \<Longrightarrow> P (\<Squnion>i. Y i)\<rbrakk>
- \<Longrightarrow> P (\<Squnion>i. Y i)"
-apply (case_tac "finite_chain Y")
-prefer 2 apply fast
-apply (unfold finite_chain_def)
-apply safe
-apply (erule lub_finch1 [THEN thelubI, THEN ssubst])
-apply assumption
-apply (erule spec)
-done
-
-lemma increasing_chain_adm_lemma:
- "\<lbrakk>chain Y; \<forall>i. P (Y i); \<And>Y. \<lbrakk>chain Y; \<forall>i. P (Y i);
- \<forall>i. \<exists>j>i. Y i \<noteq> Y j \<and> Y i \<sqsubseteq> Y j\<rbrakk> \<Longrightarrow> P (\<Squnion>i. Y i)\<rbrakk>
- \<Longrightarrow> P (\<Squnion>i. Y i)"
-apply (erule infinite_chain_adm_lemma)
-apply assumption
-apply (erule thin_rl)
-apply (unfold finite_chain_def)
-apply (unfold max_in_chain_def)
-apply (fast dest: le_imp_less_or_eq elim: chain_mono_less)
-done
+end
end
--- a/src/HOLCF/Pcpodef.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Pcpodef.thy Mon May 11 17:20:52 2009 +0200
@@ -16,22 +16,22 @@
if the ordering is defined in the standard way.
*}
-setup {* Sign.add_const_constraint (@{const_name Porder.sq_le}, NONE) *}
+setup {* Sign.add_const_constraint (@{const_name Porder.below}, NONE) *}
theorem typedef_po:
fixes Abs :: "'a::po \<Rightarrow> 'b::type"
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
shows "OFCLASS('b, po_class)"
- apply (intro_classes, unfold less)
- apply (rule refl_less)
- apply (erule (1) trans_less)
+ apply (intro_classes, unfold below)
+ apply (rule below_refl)
+ apply (erule (1) below_trans)
apply (rule type_definition.Rep_inject [OF type, THEN iffD1])
- apply (erule (1) antisym_less)
+ apply (erule (1) below_antisym)
done
-setup {* Sign.add_const_constraint (@{const_name Porder.sq_le},
- SOME @{typ "'a::sq_ord \<Rightarrow> 'a::sq_ord \<Rightarrow> bool"}) *}
+setup {* Sign.add_const_constraint (@{const_name Porder.below},
+ SOME @{typ "'a::below \<Rightarrow> 'a::below \<Rightarrow> bool"}) *}
subsection {* Proving a subtype is finite *}
@@ -58,9 +58,9 @@
subsection {* Proving a subtype is chain-finite *}
lemma monofun_Rep:
- assumes less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ assumes below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
shows "monofun Rep"
-by (rule monofunI, unfold less)
+by (rule monofunI, unfold below)
lemmas ch2ch_Rep = ch2ch_monofun [OF monofun_Rep]
lemmas ub2ub_Rep = ub2ub_monofun [OF monofun_Rep]
@@ -68,10 +68,10 @@
theorem typedef_chfin:
fixes Abs :: "'a::chfin \<Rightarrow> 'b::po"
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
shows "OFCLASS('b, chfin_class)"
apply intro_classes
- apply (drule ch2ch_Rep [OF less])
+ apply (drule ch2ch_Rep [OF below])
apply (drule chfin)
apply (unfold max_in_chain_def)
apply (simp add: type_definition.Rep_inject [OF type])
@@ -90,28 +90,28 @@
lemma Abs_inverse_lub_Rep:
fixes Abs :: "'a::cpo \<Rightarrow> 'b::po"
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and adm: "adm (\<lambda>x. x \<in> A)"
shows "chain S \<Longrightarrow> Rep (Abs (\<Squnion>i. Rep (S i))) = (\<Squnion>i. Rep (S i))"
apply (rule type_definition.Abs_inverse [OF type])
- apply (erule admD [OF adm ch2ch_Rep [OF less]])
+ apply (erule admD [OF adm ch2ch_Rep [OF below]])
apply (rule type_definition.Rep [OF type])
done
theorem typedef_lub:
fixes Abs :: "'a::cpo \<Rightarrow> 'b::po"
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and adm: "adm (\<lambda>x. x \<in> A)"
shows "chain S \<Longrightarrow> range S <<| Abs (\<Squnion>i. Rep (S i))"
- apply (frule ch2ch_Rep [OF less])
+ apply (frule ch2ch_Rep [OF below])
apply (rule is_lubI)
apply (rule ub_rangeI)
- apply (simp only: less Abs_inverse_lub_Rep [OF type less adm])
+ apply (simp only: below Abs_inverse_lub_Rep [OF type below adm])
apply (erule is_ub_thelub)
- apply (simp only: less Abs_inverse_lub_Rep [OF type less adm])
+ apply (simp only: below Abs_inverse_lub_Rep [OF type below adm])
apply (erule is_lub_thelub)
- apply (erule ub2ub_Rep [OF less])
+ apply (erule ub2ub_Rep [OF below])
done
lemmas typedef_thelub = typedef_lub [THEN thelubI, standard]
@@ -119,13 +119,13 @@
theorem typedef_cpo:
fixes Abs :: "'a::cpo \<Rightarrow> 'b::po"
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and adm: "adm (\<lambda>x. x \<in> A)"
shows "OFCLASS('b, cpo_class)"
proof
fix S::"nat \<Rightarrow> 'b" assume "chain S"
hence "range S <<| Abs (\<Squnion>i. Rep (S i))"
- by (rule typedef_lub [OF type less adm])
+ by (rule typedef_lub [OF type below adm])
thus "\<exists>x. range S <<| x" ..
qed
@@ -136,14 +136,14 @@
theorem typedef_cont_Rep:
fixes Abs :: "'a::cpo \<Rightarrow> 'b::cpo"
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and adm: "adm (\<lambda>x. x \<in> A)"
shows "cont Rep"
apply (rule contI)
- apply (simp only: typedef_thelub [OF type less adm])
- apply (simp only: Abs_inverse_lub_Rep [OF type less adm])
+ apply (simp only: typedef_thelub [OF type below adm])
+ apply (simp only: Abs_inverse_lub_Rep [OF type below adm])
apply (rule cpo_lubI)
- apply (erule ch2ch_Rep [OF less])
+ apply (erule ch2ch_Rep [OF below])
done
text {*
@@ -153,28 +153,28 @@
*}
theorem typedef_is_lubI:
- assumes less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ assumes below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
shows "range (\<lambda>i. Rep (S i)) <<| Rep x \<Longrightarrow> range S <<| x"
apply (rule is_lubI)
apply (rule ub_rangeI)
- apply (subst less)
+ apply (subst below)
apply (erule is_ub_lub)
- apply (subst less)
+ apply (subst below)
apply (erule is_lub_lub)
- apply (erule ub2ub_Rep [OF less])
+ apply (erule ub2ub_Rep [OF below])
done
theorem typedef_cont_Abs:
fixes Abs :: "'a::cpo \<Rightarrow> 'b::cpo"
fixes f :: "'c::cpo \<Rightarrow> 'a::cpo"
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and adm: "adm (\<lambda>x. x \<in> A)" (* not used *)
and f_in_A: "\<And>x. f x \<in> A"
and cont_f: "cont f"
shows "cont (\<lambda>x. Abs (f x))"
apply (rule contI)
- apply (rule typedef_is_lubI [OF less])
+ apply (rule typedef_is_lubI [OF below])
apply (simp only: type_definition.Abs_inverse [OF type f_in_A])
apply (erule cont_f [THEN contE])
done
@@ -184,15 +184,15 @@
theorem typedef_compact:
fixes Abs :: "'a::cpo \<Rightarrow> 'b::cpo"
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and adm: "adm (\<lambda>x. x \<in> A)"
shows "compact (Rep k) \<Longrightarrow> compact k"
proof (unfold compact_def)
have cont_Rep: "cont Rep"
- by (rule typedef_cont_Rep [OF type less adm])
+ by (rule typedef_cont_Rep [OF type below adm])
assume "adm (\<lambda>x. \<not> Rep k \<sqsubseteq> x)"
with cont_Rep have "adm (\<lambda>x. \<not> Rep k \<sqsubseteq> Rep x)" by (rule adm_subst)
- thus "adm (\<lambda>x. \<not> k \<sqsubseteq> x)" by (unfold less)
+ thus "adm (\<lambda>x. \<not> k \<sqsubseteq> x)" by (unfold below)
qed
subsection {* Proving a subtype is pointed *}
@@ -205,13 +205,13 @@
theorem typedef_pcpo_generic:
fixes Abs :: "'a::cpo \<Rightarrow> 'b::cpo"
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and z_in_A: "z \<in> A"
and z_least: "\<And>x. x \<in> A \<Longrightarrow> z \<sqsubseteq> x"
shows "OFCLASS('b, pcpo_class)"
apply (intro_classes)
apply (rule_tac x="Abs z" in exI, rule allI)
- apply (unfold less)
+ apply (unfold below)
apply (subst type_definition.Abs_inverse [OF type z_in_A])
apply (rule z_least [OF type_definition.Rep [OF type]])
done
@@ -224,10 +224,10 @@
theorem typedef_pcpo:
fixes Abs :: "'a::pcpo \<Rightarrow> 'b::cpo"
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and UU_in_A: "\<bottom> \<in> A"
shows "OFCLASS('b, pcpo_class)"
-by (rule typedef_pcpo_generic [OF type less UU_in_A], rule minimal)
+by (rule typedef_pcpo_generic [OF type below UU_in_A], rule minimal)
subsubsection {* Strictness of @{term Rep} and @{term Abs} *}
@@ -238,66 +238,66 @@
theorem typedef_Abs_strict:
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and UU_in_A: "\<bottom> \<in> A"
shows "Abs \<bottom> = \<bottom>"
- apply (rule UU_I, unfold less)
+ apply (rule UU_I, unfold below)
apply (simp add: type_definition.Abs_inverse [OF type UU_in_A])
done
theorem typedef_Rep_strict:
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and UU_in_A: "\<bottom> \<in> A"
shows "Rep \<bottom> = \<bottom>"
- apply (rule typedef_Abs_strict [OF type less UU_in_A, THEN subst])
+ apply (rule typedef_Abs_strict [OF type below UU_in_A, THEN subst])
apply (rule type_definition.Abs_inverse [OF type UU_in_A])
done
theorem typedef_Abs_strict_iff:
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and UU_in_A: "\<bottom> \<in> A"
shows "x \<in> A \<Longrightarrow> (Abs x = \<bottom>) = (x = \<bottom>)"
- apply (rule typedef_Abs_strict [OF type less UU_in_A, THEN subst])
+ apply (rule typedef_Abs_strict [OF type below UU_in_A, THEN subst])
apply (simp add: type_definition.Abs_inject [OF type] UU_in_A)
done
theorem typedef_Rep_strict_iff:
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and UU_in_A: "\<bottom> \<in> A"
shows "(Rep x = \<bottom>) = (x = \<bottom>)"
- apply (rule typedef_Rep_strict [OF type less UU_in_A, THEN subst])
+ apply (rule typedef_Rep_strict [OF type below UU_in_A, THEN subst])
apply (simp add: type_definition.Rep_inject [OF type])
done
theorem typedef_Abs_defined:
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and UU_in_A: "\<bottom> \<in> A"
shows "\<lbrakk>x \<noteq> \<bottom>; x \<in> A\<rbrakk> \<Longrightarrow> Abs x \<noteq> \<bottom>"
-by (simp add: typedef_Abs_strict_iff [OF type less UU_in_A])
+by (simp add: typedef_Abs_strict_iff [OF type below UU_in_A])
theorem typedef_Rep_defined:
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and UU_in_A: "\<bottom> \<in> A"
shows "x \<noteq> \<bottom> \<Longrightarrow> Rep x \<noteq> \<bottom>"
-by (simp add: typedef_Rep_strict_iff [OF type less UU_in_A])
+by (simp add: typedef_Rep_strict_iff [OF type below UU_in_A])
subsection {* Proving a subtype is flat *}
theorem typedef_flat:
fixes Abs :: "'a::flat \<Rightarrow> 'b::pcpo"
assumes type: "type_definition Rep Abs A"
- and less: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
+ and below: "op \<sqsubseteq> \<equiv> \<lambda>x y. Rep x \<sqsubseteq> Rep y"
and UU_in_A: "\<bottom> \<in> A"
shows "OFCLASS('b, flat_class)"
apply (intro_classes)
- apply (unfold less)
+ apply (unfold below)
apply (simp add: type_definition.Rep_inject [OF type, symmetric])
- apply (simp add: typedef_Rep_strict [OF type less UU_in_A])
+ apply (simp add: typedef_Rep_strict [OF type below UU_in_A])
apply (simp add: ax_flat)
done
--- a/src/HOLCF/Porder.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Porder.thy Mon May 11 17:20:52 2009 +0200
@@ -10,94 +10,105 @@
subsection {* Type class for partial orders *}
-class sq_ord =
- fixes sq_le :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
+class below =
+ fixes below :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
+begin
notation
- sq_le (infixl "<<" 55)
+ below (infixl "<<" 55)
notation (xsymbols)
- sq_le (infixl "\<sqsubseteq>" 55)
+ below (infixl "\<sqsubseteq>" 55)
+
+lemma below_eq_trans: "\<lbrakk>a \<sqsubseteq> b; b = c\<rbrakk> \<Longrightarrow> a \<sqsubseteq> c"
+ by (rule subst)
+
+lemma eq_below_trans: "\<lbrakk>a = b; b \<sqsubseteq> c\<rbrakk> \<Longrightarrow> a \<sqsubseteq> c"
+ by (rule ssubst)
-class po = sq_ord +
- assumes refl_less [iff]: "x \<sqsubseteq> x"
- assumes trans_less: "\<lbrakk>x \<sqsubseteq> y; y \<sqsubseteq> z\<rbrakk> \<Longrightarrow> x \<sqsubseteq> z"
- assumes antisym_less: "\<lbrakk>x \<sqsubseteq> y; y \<sqsubseteq> x\<rbrakk> \<Longrightarrow> x = y"
+end
+
+class po = below +
+ assumes below_refl [iff]: "x \<sqsubseteq> x"
+ assumes below_trans: "x \<sqsubseteq> y \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> x \<sqsubseteq> z"
+ assumes below_antisym: "x \<sqsubseteq> y \<Longrightarrow> y \<sqsubseteq> x \<Longrightarrow> x = y"
+begin
text {* minimal fixes least element *}
-lemma minimal2UU[OF allI] : "\<forall>x::'a::po. uu \<sqsubseteq> x \<Longrightarrow> uu = (THE u. \<forall>y. u \<sqsubseteq> y)"
-by (blast intro: theI2 antisym_less)
+lemma minimal2UU[OF allI] : "\<forall>x. uu \<sqsubseteq> x \<Longrightarrow> uu = (THE u. \<forall>y. u \<sqsubseteq> y)"
+ by (blast intro: theI2 below_antisym)
text {* the reverse law of anti-symmetry of @{term "op <<"} *}
+(* Is this rule ever useful? *)
+lemma below_antisym_inverse: "x = y \<Longrightarrow> x \<sqsubseteq> y \<and> y \<sqsubseteq> x"
+ by simp
-lemma antisym_less_inverse: "(x::'a::po) = y \<Longrightarrow> x \<sqsubseteq> y \<and> y \<sqsubseteq> x"
-by simp
-
-lemma box_less: "\<lbrakk>(a::'a::po) \<sqsubseteq> b; c \<sqsubseteq> a; b \<sqsubseteq> d\<rbrakk> \<Longrightarrow> c \<sqsubseteq> d"
-by (rule trans_less [OF trans_less])
+lemma box_below: "a \<sqsubseteq> b \<Longrightarrow> c \<sqsubseteq> a \<Longrightarrow> b \<sqsubseteq> d \<Longrightarrow> c \<sqsubseteq> d"
+ by (rule below_trans [OF below_trans])
-lemma po_eq_conv: "((x::'a::po) = y) = (x \<sqsubseteq> y \<and> y \<sqsubseteq> x)"
-by (fast elim!: antisym_less_inverse intro!: antisym_less)
-
-lemma rev_trans_less: "\<lbrakk>(y::'a::po) \<sqsubseteq> z; x \<sqsubseteq> y\<rbrakk> \<Longrightarrow> x \<sqsubseteq> z"
-by (rule trans_less)
+lemma po_eq_conv: "x = y \<longleftrightarrow> x \<sqsubseteq> y \<and> y \<sqsubseteq> x"
+ by (fast intro!: below_antisym)
-lemma sq_ord_less_eq_trans: "\<lbrakk>a \<sqsubseteq> b; b = c\<rbrakk> \<Longrightarrow> a \<sqsubseteq> c"
-by (rule subst)
+lemma rev_below_trans: "y \<sqsubseteq> z \<Longrightarrow> x \<sqsubseteq> y \<Longrightarrow> x \<sqsubseteq> z"
+ by (rule below_trans)
-lemma sq_ord_eq_less_trans: "\<lbrakk>a = b; b \<sqsubseteq> c\<rbrakk> \<Longrightarrow> a \<sqsubseteq> c"
-by (rule ssubst)
+lemma not_below2not_eq: "\<not> x \<sqsubseteq> y \<Longrightarrow> x \<noteq> y"
+ by auto
+
+end
lemmas HOLCF_trans_rules [trans] =
- trans_less
- antisym_less
- sq_ord_less_eq_trans
- sq_ord_eq_less_trans
+ below_trans
+ below_antisym
+ below_eq_trans
+ eq_below_trans
+
+context po
+begin
subsection {* Upper bounds *}
-definition
- is_ub :: "['a set, 'a::po] \<Rightarrow> bool" (infixl "<|" 55) where
- "(S <| x) = (\<forall>y. y \<in> S \<longrightarrow> y \<sqsubseteq> x)"
+definition is_ub :: "'a set \<Rightarrow> 'a \<Rightarrow> bool" (infixl "<|" 55) where
+ "S <| x \<longleftrightarrow> (\<forall>y. y \<in> S \<longrightarrow> y \<sqsubseteq> x)"
lemma is_ubI: "(\<And>x. x \<in> S \<Longrightarrow> x \<sqsubseteq> u) \<Longrightarrow> S <| u"
-by (simp add: is_ub_def)
+ by (simp add: is_ub_def)
lemma is_ubD: "\<lbrakk>S <| u; x \<in> S\<rbrakk> \<Longrightarrow> x \<sqsubseteq> u"
-by (simp add: is_ub_def)
+ by (simp add: is_ub_def)
lemma ub_imageI: "(\<And>x. x \<in> S \<Longrightarrow> f x \<sqsubseteq> u) \<Longrightarrow> (\<lambda>x. f x) ` S <| u"
-unfolding is_ub_def by fast
+ unfolding is_ub_def by fast
lemma ub_imageD: "\<lbrakk>f ` S <| u; x \<in> S\<rbrakk> \<Longrightarrow> f x \<sqsubseteq> u"
-unfolding is_ub_def by fast
+ unfolding is_ub_def by fast
lemma ub_rangeI: "(\<And>i. S i \<sqsubseteq> x) \<Longrightarrow> range S <| x"
-unfolding is_ub_def by fast
+ unfolding is_ub_def by fast
lemma ub_rangeD: "range S <| x \<Longrightarrow> S i \<sqsubseteq> x"
-unfolding is_ub_def by fast
+ unfolding is_ub_def by fast
lemma is_ub_empty [simp]: "{} <| u"
-unfolding is_ub_def by fast
+ unfolding is_ub_def by fast
lemma is_ub_insert [simp]: "(insert x A) <| y = (x \<sqsubseteq> y \<and> A <| y)"
-unfolding is_ub_def by fast
+ unfolding is_ub_def by fast
lemma is_ub_upward: "\<lbrakk>S <| x; x \<sqsubseteq> y\<rbrakk> \<Longrightarrow> S <| y"
-unfolding is_ub_def by (fast intro: trans_less)
+ unfolding is_ub_def by (fast intro: below_trans)
subsection {* Least upper bounds *}
-definition
- is_lub :: "['a set, 'a::po] \<Rightarrow> bool" (infixl "<<|" 55) where
- "(S <<| x) = (S <| x \<and> (\<forall>u. S <| u \<longrightarrow> x \<sqsubseteq> u))"
+definition is_lub :: "'a set \<Rightarrow> 'a \<Rightarrow> bool" (infixl "<<|" 55) where
+ "S <<| x \<longleftrightarrow> S <| x \<and> (\<forall>u. S <| u \<longrightarrow> x \<sqsubseteq> u)"
-definition
- lub :: "'a set \<Rightarrow> 'a::po" where
+definition lub :: "'a set \<Rightarrow> 'a" where
"lub S = (THE x. S <<| x)"
+end
+
syntax
"_BLub" :: "[pttrn, 'a set, 'b] \<Rightarrow> 'b" ("(3LUB _:_./ _)" [0,0, 10] 10)
@@ -107,6 +118,9 @@
translations
"LUB x:A. t" == "CONST lub ((%x. t) ` A)"
+context po
+begin
+
abbreviation
Lub (binder "LUB " 10) where
"LUB n. t n == lub (range t)"
@@ -117,19 +131,19 @@
text {* access to some definition as inference rule *}
lemma is_lubD1: "S <<| x \<Longrightarrow> S <| x"
-unfolding is_lub_def by fast
+ unfolding is_lub_def by fast
lemma is_lub_lub: "\<lbrakk>S <<| x; S <| u\<rbrakk> \<Longrightarrow> x \<sqsubseteq> u"
-unfolding is_lub_def by fast
+ unfolding is_lub_def by fast
lemma is_lubI: "\<lbrakk>S <| x; \<And>u. S <| u \<Longrightarrow> x \<sqsubseteq> u\<rbrakk> \<Longrightarrow> S <<| x"
-unfolding is_lub_def by fast
+ unfolding is_lub_def by fast
text {* lubs are unique *}
lemma unique_lub: "\<lbrakk>S <<| x; S <<| y\<rbrakk> \<Longrightarrow> x = y"
apply (unfold is_lub_def is_ub_def)
-apply (blast intro: antisym_less)
+apply (blast intro: below_antisym)
done
text {* technical lemmas about @{term lub} and @{term is_lub} *}
@@ -142,60 +156,59 @@
done
lemma thelubI: "M <<| l \<Longrightarrow> lub M = l"
-by (rule unique_lub [OF lubI])
+ by (rule unique_lub [OF lubI])
lemma is_lub_singleton: "{x} <<| x"
-by (simp add: is_lub_def)
+ by (simp add: is_lub_def)
lemma lub_singleton [simp]: "lub {x} = x"
-by (rule thelubI [OF is_lub_singleton])
+ by (rule thelubI [OF is_lub_singleton])
lemma is_lub_bin: "x \<sqsubseteq> y \<Longrightarrow> {x, y} <<| y"
-by (simp add: is_lub_def)
+ by (simp add: is_lub_def)
lemma lub_bin: "x \<sqsubseteq> y \<Longrightarrow> lub {x, y} = y"
-by (rule is_lub_bin [THEN thelubI])
+ by (rule is_lub_bin [THEN thelubI])
lemma is_lub_maximal: "\<lbrakk>S <| x; x \<in> S\<rbrakk> \<Longrightarrow> S <<| x"
-by (erule is_lubI, erule (1) is_ubD)
+ by (erule is_lubI, erule (1) is_ubD)
lemma lub_maximal: "\<lbrakk>S <| x; x \<in> S\<rbrakk> \<Longrightarrow> lub S = x"
-by (rule is_lub_maximal [THEN thelubI])
+ by (rule is_lub_maximal [THEN thelubI])
subsection {* Countable chains *}
-definition
+definition chain :: "(nat \<Rightarrow> 'a) \<Rightarrow> bool" where
-- {* Here we use countable chains and I prefer to code them as functions! *}
- chain :: "(nat \<Rightarrow> 'a::po) \<Rightarrow> bool" where
"chain Y = (\<forall>i. Y i \<sqsubseteq> Y (Suc i))"
lemma chainI: "(\<And>i. Y i \<sqsubseteq> Y (Suc i)) \<Longrightarrow> chain Y"
-unfolding chain_def by fast
+ unfolding chain_def by fast
lemma chainE: "chain Y \<Longrightarrow> Y i \<sqsubseteq> Y (Suc i)"
-unfolding chain_def by fast
+ unfolding chain_def by fast
text {* chains are monotone functions *}
lemma chain_mono_less: "\<lbrakk>chain Y; i < j\<rbrakk> \<Longrightarrow> Y i \<sqsubseteq> Y j"
-by (erule less_Suc_induct, erule chainE, erule trans_less)
+ by (erule less_Suc_induct, erule chainE, erule below_trans)
lemma chain_mono: "\<lbrakk>chain Y; i \<le> j\<rbrakk> \<Longrightarrow> Y i \<sqsubseteq> Y j"
-by (cases "i = j", simp, simp add: chain_mono_less)
+ by (cases "i = j", simp, simp add: chain_mono_less)
lemma chain_shift: "chain Y \<Longrightarrow> chain (\<lambda>i. Y (i + j))"
-by (rule chainI, simp, erule chainE)
+ by (rule chainI, simp, erule chainE)
text {* technical lemmas about (least) upper bounds of chains *}
lemma is_ub_lub: "range S <<| x \<Longrightarrow> S i \<sqsubseteq> x"
-by (rule is_lubD1 [THEN ub_rangeD])
+ by (rule is_lubD1 [THEN ub_rangeD])
lemma is_ub_range_shift:
"chain S \<Longrightarrow> range (\<lambda>i. S (i + j)) <| x = range S <| x"
apply (rule iffI)
apply (rule ub_rangeI)
-apply (rule_tac y="S (i + j)" in trans_less)
+apply (rule_tac y="S (i + j)" in below_trans)
apply (erule chain_mono)
apply (rule le_add1)
apply (erule ub_rangeD)
@@ -205,45 +218,43 @@
lemma is_lub_range_shift:
"chain S \<Longrightarrow> range (\<lambda>i. S (i + j)) <<| x = range S <<| x"
-by (simp add: is_lub_def is_ub_range_shift)
+ by (simp add: is_lub_def is_ub_range_shift)
text {* the lub of a constant chain is the constant *}
lemma chain_const [simp]: "chain (\<lambda>i. c)"
-by (simp add: chainI)
+ by (simp add: chainI)
lemma lub_const: "range (\<lambda>x. c) <<| c"
by (blast dest: ub_rangeD intro: is_lubI ub_rangeI)
lemma thelub_const [simp]: "(\<Squnion>i. c) = c"
-by (rule lub_const [THEN thelubI])
+ by (rule lub_const [THEN thelubI])
subsection {* Finite chains *}
-definition
+definition max_in_chain :: "nat \<Rightarrow> (nat \<Rightarrow> 'a) \<Rightarrow> bool" where
-- {* finite chains, needed for monotony of continuous functions *}
- max_in_chain :: "[nat, nat \<Rightarrow> 'a::po] \<Rightarrow> bool" where
- "max_in_chain i C = (\<forall>j. i \<le> j \<longrightarrow> C i = C j)"
+ "max_in_chain i C \<longleftrightarrow> (\<forall>j. i \<le> j \<longrightarrow> C i = C j)"
-definition
- finite_chain :: "(nat \<Rightarrow> 'a::po) \<Rightarrow> bool" where
+definition finite_chain :: "(nat \<Rightarrow> 'a) \<Rightarrow> bool" where
"finite_chain C = (chain C \<and> (\<exists>i. max_in_chain i C))"
text {* results about finite chains *}
lemma max_in_chainI: "(\<And>j. i \<le> j \<Longrightarrow> Y i = Y j) \<Longrightarrow> max_in_chain i Y"
-unfolding max_in_chain_def by fast
+ unfolding max_in_chain_def by fast
lemma max_in_chainD: "\<lbrakk>max_in_chain i Y; i \<le> j\<rbrakk> \<Longrightarrow> Y i = Y j"
-unfolding max_in_chain_def by fast
+ unfolding max_in_chain_def by fast
lemma finite_chainI:
"\<lbrakk>chain C; max_in_chain i C\<rbrakk> \<Longrightarrow> finite_chain C"
-unfolding finite_chain_def by fast
+ unfolding finite_chain_def by fast
lemma finite_chainE:
"\<lbrakk>finite_chain C; \<And>i. \<lbrakk>chain C; max_in_chain i C\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
-unfolding finite_chain_def by fast
+ unfolding finite_chain_def by fast
lemma lub_finch1: "\<lbrakk>chain C; max_in_chain i C\<rbrakk> \<Longrightarrow> range C <<| C i"
apply (rule is_lubI)
@@ -302,7 +313,7 @@
apply (erule exE)
apply (rule finite_chainI, assumption)
apply (rule max_in_chainI)
- apply (rule antisym_less)
+ apply (rule below_antisym)
apply (erule (1) chain_mono)
apply (erule spec)
apply (rule finite_range_has_max)
@@ -311,11 +322,11 @@
done
lemma bin_chain: "x \<sqsubseteq> y \<Longrightarrow> chain (\<lambda>i. if i=0 then x else y)"
-by (rule chainI, simp)
+ by (rule chainI, simp)
lemma bin_chainmax:
"x \<sqsubseteq> y \<Longrightarrow> max_in_chain (Suc 0) (\<lambda>i. if i=0 then x else y)"
-unfolding max_in_chain_def by simp
+ unfolding max_in_chain_def by simp
lemma lub_bin_chain:
"x \<sqsubseteq> y \<Longrightarrow> range (\<lambda>i::nat. if i=0 then x else y) <<| y"
@@ -328,36 +339,35 @@
text {* the maximal element in a chain is its lub *}
lemma lub_chain_maxelem: "\<lbrakk>Y i = c; \<forall>i. Y i \<sqsubseteq> c\<rbrakk> \<Longrightarrow> lub (range Y) = c"
-by (blast dest: ub_rangeD intro: thelubI is_lubI ub_rangeI)
+ by (blast dest: ub_rangeD intro: thelubI is_lubI ub_rangeI)
subsection {* Directed sets *}
-definition
- directed :: "'a::po set \<Rightarrow> bool" where
- "directed S = ((\<exists>x. x \<in> S) \<and> (\<forall>x\<in>S. \<forall>y\<in>S. \<exists>z\<in>S. x \<sqsubseteq> z \<and> y \<sqsubseteq> z))"
+definition directed :: "'a set \<Rightarrow> bool" where
+ "directed S \<longleftrightarrow> (\<exists>x. x \<in> S) \<and> (\<forall>x\<in>S. \<forall>y\<in>S. \<exists>z\<in>S. x \<sqsubseteq> z \<and> y \<sqsubseteq> z)"
lemma directedI:
assumes 1: "\<exists>z. z \<in> S"
assumes 2: "\<And>x y. \<lbrakk>x \<in> S; y \<in> S\<rbrakk> \<Longrightarrow> \<exists>z\<in>S. x \<sqsubseteq> z \<and> y \<sqsubseteq> z"
shows "directed S"
-unfolding directed_def using prems by fast
+ unfolding directed_def using prems by fast
lemma directedD1: "directed S \<Longrightarrow> \<exists>z. z \<in> S"
-unfolding directed_def by fast
+ unfolding directed_def by fast
lemma directedD2: "\<lbrakk>directed S; x \<in> S; y \<in> S\<rbrakk> \<Longrightarrow> \<exists>z\<in>S. x \<sqsubseteq> z \<and> y \<sqsubseteq> z"
-unfolding directed_def by fast
+ unfolding directed_def by fast
lemma directedE1:
assumes S: "directed S"
obtains z where "z \<in> S"
-by (insert directedD1 [OF S], fast)
+ by (insert directedD1 [OF S], fast)
lemma directedE2:
assumes S: "directed S"
assumes x: "x \<in> S" and y: "y \<in> S"
obtains z where "z \<in> S" "x \<sqsubseteq> z" "y \<sqsubseteq> z"
-by (insert directedD2 [OF S x y], fast)
+ by (insert directedD2 [OF S x y], fast)
lemma directed_finiteI:
assumes U: "\<And>U. \<lbrakk>finite U; U \<subseteq> S\<rbrakk> \<Longrightarrow> \<exists>z\<in>S. U <| z"
@@ -395,13 +405,13 @@
qed
lemma not_directed_empty [simp]: "\<not> directed {}"
-by (rule notI, drule directedD1, simp)
+ by (rule notI, drule directedD1, simp)
lemma directed_singleton: "directed {x}"
-by (rule directedI, auto)
+ by (rule directedI, auto)
lemma directed_bin: "x \<sqsubseteq> y \<Longrightarrow> directed {x, y}"
-by (rule directedI, auto)
+ by (rule directedI, auto)
lemma directed_chain: "chain S \<Longrightarrow> directed (range S)"
apply (rule directedI)
@@ -412,4 +422,33 @@
apply simp
done
+text {* lemmata for improved admissibility introdution rule *}
+
+lemma infinite_chain_adm_lemma:
+ "\<lbrakk>chain Y; \<forall>i. P (Y i);
+ \<And>Y. \<lbrakk>chain Y; \<forall>i. P (Y i); \<not> finite_chain Y\<rbrakk> \<Longrightarrow> P (\<Squnion>i. Y i)\<rbrakk>
+ \<Longrightarrow> P (\<Squnion>i. Y i)"
+apply (case_tac "finite_chain Y")
+prefer 2 apply fast
+apply (unfold finite_chain_def)
+apply safe
+apply (erule lub_finch1 [THEN thelubI, THEN ssubst])
+apply assumption
+apply (erule spec)
+done
+
+lemma increasing_chain_adm_lemma:
+ "\<lbrakk>chain Y; \<forall>i. P (Y i); \<And>Y. \<lbrakk>chain Y; \<forall>i. P (Y i);
+ \<forall>i. \<exists>j>i. Y i \<noteq> Y j \<and> Y i \<sqsubseteq> Y j\<rbrakk> \<Longrightarrow> P (\<Squnion>i. Y i)\<rbrakk>
+ \<Longrightarrow> P (\<Squnion>i. Y i)"
+apply (erule infinite_chain_adm_lemma)
+apply assumption
+apply (erule thin_rl)
+apply (unfold finite_chain_def)
+apply (unfold max_in_chain_def)
+apply (fast dest: le_imp_less_or_eq elim: chain_mono_less)
+done
+
end
+
+end
--- a/src/HOLCF/Product_Cpo.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Product_Cpo.thy Mon May 11 17:20:52 2009 +0200
@@ -12,11 +12,11 @@
subsection {* Type @{typ unit} is a pcpo *}
-instantiation unit :: sq_ord
+instantiation unit :: below
begin
definition
- less_unit_def [simp]: "x \<sqsubseteq> (y::unit) \<equiv> True"
+ below_unit_def [simp]: "x \<sqsubseteq> (y::unit) \<longleftrightarrow> True"
instance ..
end
@@ -32,11 +32,11 @@
subsection {* Product type is a partial order *}
-instantiation "*" :: (sq_ord, sq_ord) sq_ord
+instantiation "*" :: (below, below) below
begin
definition
- less_cprod_def: "(op \<sqsubseteq>) \<equiv> \<lambda>p1 p2. (fst p1 \<sqsubseteq> fst p2 \<and> snd p1 \<sqsubseteq> snd p2)"
+ below_prod_def: "(op \<sqsubseteq>) \<equiv> \<lambda>p1 p2. (fst p1 \<sqsubseteq> fst p2 \<and> snd p1 \<sqsubseteq> snd p2)"
instance ..
end
@@ -45,26 +45,26 @@
proof
fix x :: "'a \<times> 'b"
show "x \<sqsubseteq> x"
- unfolding less_cprod_def by simp
+ unfolding below_prod_def by simp
next
fix x y :: "'a \<times> 'b"
assume "x \<sqsubseteq> y" "y \<sqsubseteq> x" thus "x = y"
- unfolding less_cprod_def Pair_fst_snd_eq
- by (fast intro: antisym_less)
+ unfolding below_prod_def Pair_fst_snd_eq
+ by (fast intro: below_antisym)
next
fix x y z :: "'a \<times> 'b"
assume "x \<sqsubseteq> y" "y \<sqsubseteq> z" thus "x \<sqsubseteq> z"
- unfolding less_cprod_def
- by (fast intro: trans_less)
+ unfolding below_prod_def
+ by (fast intro: below_trans)
qed
subsection {* Monotonicity of @{text "(_,_)"}, @{term fst}, @{term snd} *}
-lemma prod_lessI: "\<lbrakk>fst p \<sqsubseteq> fst q; snd p \<sqsubseteq> snd q\<rbrakk> \<Longrightarrow> p \<sqsubseteq> q"
-unfolding less_cprod_def by simp
+lemma prod_belowI: "\<lbrakk>fst p \<sqsubseteq> fst q; snd p \<sqsubseteq> snd q\<rbrakk> \<Longrightarrow> p \<sqsubseteq> q"
+unfolding below_prod_def by simp
-lemma Pair_less_iff [simp]: "(a, b) \<sqsubseteq> (c, d) \<longleftrightarrow> a \<sqsubseteq> c \<and> b \<sqsubseteq> d"
-unfolding less_cprod_def by simp
+lemma Pair_below_iff [simp]: "(a, b) \<sqsubseteq> (c, d) \<longleftrightarrow> a \<sqsubseteq> c \<and> b \<sqsubseteq> d"
+unfolding below_prod_def by simp
text {* Pair @{text "(_,_)"} is monotone in both arguments *}
@@ -81,20 +81,20 @@
text {* @{term fst} and @{term snd} are monotone *}
lemma monofun_fst: "monofun fst"
-by (simp add: monofun_def less_cprod_def)
+by (simp add: monofun_def below_prod_def)
lemma monofun_snd: "monofun snd"
-by (simp add: monofun_def less_cprod_def)
+by (simp add: monofun_def below_prod_def)
subsection {* Product type is a cpo *}
lemma is_lub_Pair:
"\<lbrakk>range X <<| x; range Y <<| y\<rbrakk> \<Longrightarrow> range (\<lambda>i. (X i, Y i)) <<| (x, y)"
apply (rule is_lubI [OF ub_rangeI])
-apply (simp add: less_cprod_def is_ub_lub)
+apply (simp add: below_prod_def is_ub_lub)
apply (frule ub2ub_monofun [OF monofun_fst])
apply (drule ub2ub_monofun [OF monofun_snd])
-apply (simp add: less_cprod_def is_lub_lub)
+apply (simp add: below_prod_def is_lub_lub)
done
lemma lub_cprod:
@@ -134,14 +134,14 @@
proof
fix x y :: "'a \<times> 'b"
show "x \<sqsubseteq> y \<longleftrightarrow> x = y"
- unfolding less_cprod_def Pair_fst_snd_eq
+ unfolding below_prod_def Pair_fst_snd_eq
by simp
qed
subsection {* Product type is pointed *}
lemma minimal_cprod: "(\<bottom>, \<bottom>) \<sqsubseteq> p"
-by (simp add: less_cprod_def)
+by (simp add: below_prod_def)
instance "*" :: (pcpo, pcpo) pcpo
by intro_classes (fast intro: minimal_cprod)
@@ -206,31 +206,71 @@
assumes f: "cont (\<lambda>x. f x)"
assumes g: "cont (\<lambda>x. g x)"
shows "cont (\<lambda>x. (f x, g x))"
-apply (rule cont2cont_apply [OF _ cont_pair1 f])
-apply (rule cont2cont_apply [OF _ cont_pair2 g])
+apply (rule cont_apply [OF f cont_pair1])
+apply (rule cont_apply [OF g cont_pair2])
apply (rule cont_const)
done
-lemmas cont2cont_fst [cont2cont] = cont2cont_compose [OF cont_fst]
+lemmas cont2cont_fst [cont2cont] = cont_compose [OF cont_fst]
+
+lemmas cont2cont_snd [cont2cont] = cont_compose [OF cont_snd]
+
+lemma cont2cont_split:
+ assumes f1: "\<And>a b. cont (\<lambda>x. f x a b)"
+ assumes f2: "\<And>x b. cont (\<lambda>a. f x a b)"
+ assumes f3: "\<And>x a. cont (\<lambda>b. f x a b)"
+ assumes g: "cont (\<lambda>x. g x)"
+ shows "cont (\<lambda>x. split (\<lambda>a b. f x a b) (g x))"
+unfolding split_def
+apply (rule cont_apply [OF g])
+apply (rule cont_apply [OF cont_fst f2])
+apply (rule cont_apply [OF cont_snd f3])
+apply (rule cont_const)
+apply (rule f1)
+done
+
+lemma cont_fst_snd_D1:
+ "cont (\<lambda>p. f (fst p) (snd p)) \<Longrightarrow> cont (\<lambda>x. f x y)"
+by (drule cont_compose [OF _ cont_pair1], simp)
-lemmas cont2cont_snd [cont2cont] = cont2cont_compose [OF cont_snd]
+lemma cont_fst_snd_D2:
+ "cont (\<lambda>p. f (fst p) (snd p)) \<Longrightarrow> cont (\<lambda>y. f x y)"
+by (drule cont_compose [OF _ cont_pair2], simp)
+
+lemma cont2cont_split' [cont2cont]:
+ assumes f: "cont (\<lambda>p. f (fst p) (fst (snd p)) (snd (snd p)))"
+ assumes g: "cont (\<lambda>x. g x)"
+ shows "cont (\<lambda>x. split (f x) (g x))"
+proof -
+ note f1 = f [THEN cont_fst_snd_D1]
+ note f2 = f [THEN cont_fst_snd_D2, THEN cont_fst_snd_D1]
+ note f3 = f [THEN cont_fst_snd_D2, THEN cont_fst_snd_D2]
+ show ?thesis
+ unfolding split_def
+ apply (rule cont_apply [OF g])
+ apply (rule cont_apply [OF cont_fst f2])
+ apply (rule cont_apply [OF cont_snd f3])
+ apply (rule cont_const)
+ apply (rule f1)
+ done
+qed
subsection {* Compactness and chain-finiteness *}
-lemma fst_less_iff: "fst (x::'a \<times> 'b) \<sqsubseteq> y \<longleftrightarrow> x \<sqsubseteq> (y, snd x)"
-unfolding less_cprod_def by simp
+lemma fst_below_iff: "fst (x::'a \<times> 'b) \<sqsubseteq> y \<longleftrightarrow> x \<sqsubseteq> (y, snd x)"
+unfolding below_prod_def by simp
-lemma snd_less_iff: "snd (x::'a \<times> 'b) \<sqsubseteq> y = x \<sqsubseteq> (fst x, y)"
-unfolding less_cprod_def by simp
+lemma snd_below_iff: "snd (x::'a \<times> 'b) \<sqsubseteq> y \<longleftrightarrow> x \<sqsubseteq> (fst x, y)"
+unfolding below_prod_def by simp
lemma compact_fst: "compact x \<Longrightarrow> compact (fst x)"
-by (rule compactI, simp add: fst_less_iff)
+by (rule compactI, simp add: fst_below_iff)
lemma compact_snd: "compact x \<Longrightarrow> compact (snd x)"
-by (rule compactI, simp add: snd_less_iff)
+by (rule compactI, simp add: snd_below_iff)
lemma compact_Pair: "\<lbrakk>compact x; compact y\<rbrakk> \<Longrightarrow> compact (x, y)"
-by (rule compactI, simp add: less_cprod_def)
+by (rule compactI, simp add: below_prod_def)
lemma compact_Pair_iff [simp]: "compact (x, y) \<longleftrightarrow> compact x \<and> compact y"
apply (safe intro!: compact_Pair)
--- a/src/HOLCF/Sprod.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Sprod.thy Mon May 11 17:20:52 2009 +0200
@@ -20,7 +20,7 @@
by (rule typedef_finite_po [OF type_definition_Sprod])
instance "**" :: ("{chfin,pcpo}", "{chfin,pcpo}") chfin
-by (rule typedef_chfin [OF type_definition_Sprod less_Sprod_def])
+by (rule typedef_chfin [OF type_definition_Sprod below_Sprod_def])
syntax (xsymbols)
"**" :: "[type, type] => type" ("(_ \<otimes>/ _)" [21,20] 20)
@@ -67,7 +67,7 @@
by (simp add: cont_Abs_Sprod Abs_Sprod_inverse spair_lemma)
lemmas Rep_Sprod_simps =
- Rep_Sprod_inject [symmetric] less_Sprod_def
+ Rep_Sprod_inject [symmetric] below_Sprod_def
Rep_Sprod_strict Rep_Sprod_spair
lemma Exh_Sprod:
@@ -99,7 +99,7 @@
lemma spair_strict_iff [simp]: "((:x, y:) = \<bottom>) = (x = \<bottom> \<or> y = \<bottom>)"
by (simp add: Rep_Sprod_simps strictify_conv_if)
-lemma spair_less_iff:
+lemma spair_below_iff:
"((:a, b:) \<sqsubseteq> (:c, d:)) = (a = \<bottom> \<or> b = \<bottom> \<or> (a \<sqsubseteq> c \<and> b \<sqsubseteq> d))"
by (simp add: Rep_Sprod_simps strictify_conv_if)
@@ -160,38 +160,38 @@
lemma surjective_pairing_Sprod2: "(:sfst\<cdot>p, ssnd\<cdot>p:) = p"
by (cases p, simp_all)
-lemma less_sprod: "x \<sqsubseteq> y = (sfst\<cdot>x \<sqsubseteq> sfst\<cdot>y \<and> ssnd\<cdot>x \<sqsubseteq> ssnd\<cdot>y)"
-apply (simp add: less_Sprod_def sfst_def ssnd_def cont_Rep_Sprod)
-apply (rule less_cprod)
+lemma below_sprod: "x \<sqsubseteq> y = (sfst\<cdot>x \<sqsubseteq> sfst\<cdot>y \<and> ssnd\<cdot>x \<sqsubseteq> ssnd\<cdot>y)"
+apply (simp add: below_Sprod_def sfst_def ssnd_def cont_Rep_Sprod)
+apply (rule below_cprod)
done
lemma eq_sprod: "(x = y) = (sfst\<cdot>x = sfst\<cdot>y \<and> ssnd\<cdot>x = ssnd\<cdot>y)"
-by (auto simp add: po_eq_conv less_sprod)
+by (auto simp add: po_eq_conv below_sprod)
-lemma spair_less:
+lemma spair_below:
"\<lbrakk>x \<noteq> \<bottom>; y \<noteq> \<bottom>\<rbrakk> \<Longrightarrow> (:x, y:) \<sqsubseteq> (:a, b:) = (x \<sqsubseteq> a \<and> y \<sqsubseteq> b)"
apply (cases "a = \<bottom>", simp)
apply (cases "b = \<bottom>", simp)
-apply (simp add: less_sprod)
+apply (simp add: below_sprod)
done
-lemma sfst_less_iff: "sfst\<cdot>x \<sqsubseteq> y = x \<sqsubseteq> (:y, ssnd\<cdot>x:)"
+lemma sfst_below_iff: "sfst\<cdot>x \<sqsubseteq> y = x \<sqsubseteq> (:y, ssnd\<cdot>x:)"
apply (cases "x = \<bottom>", simp, cases "y = \<bottom>", simp)
-apply (simp add: less_sprod)
+apply (simp add: below_sprod)
done
-lemma ssnd_less_iff: "ssnd\<cdot>x \<sqsubseteq> y = x \<sqsubseteq> (:sfst\<cdot>x, y:)"
+lemma ssnd_below_iff: "ssnd\<cdot>x \<sqsubseteq> y = x \<sqsubseteq> (:sfst\<cdot>x, y:)"
apply (cases "x = \<bottom>", simp, cases "y = \<bottom>", simp)
-apply (simp add: less_sprod)
+apply (simp add: below_sprod)
done
subsection {* Compactness *}
lemma compact_sfst: "compact x \<Longrightarrow> compact (sfst\<cdot>x)"
-by (rule compactI, simp add: sfst_less_iff)
+by (rule compactI, simp add: sfst_below_iff)
lemma compact_ssnd: "compact x \<Longrightarrow> compact (ssnd\<cdot>x)"
-by (rule compactI, simp add: ssnd_less_iff)
+by (rule compactI, simp add: ssnd_below_iff)
lemma compact_spair: "\<lbrakk>compact x; compact y\<rbrakk> \<Longrightarrow> compact (:x, y:)"
by (rule compact_Sprod, simp add: Rep_Sprod_spair strictify_conv_if)
@@ -224,7 +224,7 @@
assume "x \<sqsubseteq> y" thus "x = \<bottom> \<or> x = y"
apply (induct x, simp)
apply (induct y, simp)
- apply (simp add: spair_less_iff flat_less_iff)
+ apply (simp add: spair_below_iff flat_below_iff)
done
qed
--- a/src/HOLCF/Ssum.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Ssum.thy Mon May 11 17:20:52 2009 +0200
@@ -22,7 +22,7 @@
by (rule typedef_finite_po [OF type_definition_Ssum])
instance "++" :: ("{chfin,pcpo}", "{chfin,pcpo}") chfin
-by (rule typedef_chfin [OF type_definition_Ssum less_Ssum_def])
+by (rule typedef_chfin [OF type_definition_Ssum below_Ssum_def])
syntax (xsymbols)
"++" :: "[type, type] => type" ("(_ \<oplus>/ _)" [21, 20] 20)
@@ -61,17 +61,17 @@
text {* Ordering *}
-lemma sinl_less [simp]: "(sinl\<cdot>x \<sqsubseteq> sinl\<cdot>y) = (x \<sqsubseteq> y)"
-by (simp add: less_Ssum_def Rep_Ssum_sinl strictify_conv_if)
+lemma sinl_below [simp]: "(sinl\<cdot>x \<sqsubseteq> sinl\<cdot>y) = (x \<sqsubseteq> y)"
+by (simp add: below_Ssum_def Rep_Ssum_sinl strictify_conv_if)
-lemma sinr_less [simp]: "(sinr\<cdot>x \<sqsubseteq> sinr\<cdot>y) = (x \<sqsubseteq> y)"
-by (simp add: less_Ssum_def Rep_Ssum_sinr strictify_conv_if)
+lemma sinr_below [simp]: "(sinr\<cdot>x \<sqsubseteq> sinr\<cdot>y) = (x \<sqsubseteq> y)"
+by (simp add: below_Ssum_def Rep_Ssum_sinr strictify_conv_if)
-lemma sinl_less_sinr [simp]: "(sinl\<cdot>x \<sqsubseteq> sinr\<cdot>y) = (x = \<bottom>)"
-by (simp add: less_Ssum_def Rep_Ssum_sinl Rep_Ssum_sinr strictify_conv_if)
+lemma sinl_below_sinr [simp]: "(sinl\<cdot>x \<sqsubseteq> sinr\<cdot>y) = (x = \<bottom>)"
+by (simp add: below_Ssum_def Rep_Ssum_sinl Rep_Ssum_sinr strictify_conv_if)
-lemma sinr_less_sinl [simp]: "(sinr\<cdot>x \<sqsubseteq> sinl\<cdot>y) = (x = \<bottom>)"
-by (simp add: less_Ssum_def Rep_Ssum_sinl Rep_Ssum_sinr strictify_conv_if)
+lemma sinr_below_sinl [simp]: "(sinr\<cdot>x \<sqsubseteq> sinl\<cdot>y) = (x = \<bottom>)"
+by (simp add: below_Ssum_def Rep_Ssum_sinl Rep_Ssum_sinr strictify_conv_if)
text {* Equality *}
@@ -167,10 +167,10 @@
"\<lbrakk>\<And>x. p = sinl\<cdot>x \<Longrightarrow> Q; \<And>y. p = sinr\<cdot>y \<Longrightarrow> Q\<rbrakk> \<Longrightarrow> Q"
by (cases p, simp only: sinl_strict [symmetric], simp, simp)
-lemma less_sinlD: "p \<sqsubseteq> sinl\<cdot>x \<Longrightarrow> \<exists>y. p = sinl\<cdot>y \<and> y \<sqsubseteq> x"
+lemma below_sinlD: "p \<sqsubseteq> sinl\<cdot>x \<Longrightarrow> \<exists>y. p = sinl\<cdot>y \<and> y \<sqsubseteq> x"
by (cases p, rule_tac x="\<bottom>" in exI, simp_all)
-lemma less_sinrD: "p \<sqsubseteq> sinr\<cdot>x \<Longrightarrow> \<exists>y. p = sinr\<cdot>y \<and> y \<sqsubseteq> x"
+lemma below_sinrD: "p \<sqsubseteq> sinr\<cdot>x \<Longrightarrow> \<exists>y. p = sinr\<cdot>y \<and> y \<sqsubseteq> x"
by (cases p, rule_tac x="\<bottom>" in exI, simp_all)
subsection {* Case analysis combinator *}
@@ -207,8 +207,8 @@
instance "++" :: (flat, flat) flat
apply (intro_classes, clarify)
apply (rule_tac p=x in ssumE, simp)
-apply (rule_tac p=y in ssumE, simp_all add: flat_less_iff)
-apply (rule_tac p=y in ssumE, simp_all add: flat_less_iff)
+apply (rule_tac p=y in ssumE, simp_all add: flat_below_iff)
+apply (rule_tac p=y in ssumE, simp_all add: flat_below_iff)
done
subsection {* Strict sum is a bifinite domain *}
--- a/src/HOLCF/Sum_Cpo.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Sum_Cpo.thy Mon May 11 17:20:52 2009 +0200
@@ -10,28 +10,28 @@
subsection {* Ordering on type @{typ "'a + 'b"} *}
-instantiation "+" :: (sq_ord, sq_ord) sq_ord
+instantiation "+" :: (below, below) below
begin
-definition
- less_sum_def: "x \<sqsubseteq> y \<equiv> case x of
+definition below_sum_def:
+ "x \<sqsubseteq> y \<equiv> case x of
Inl a \<Rightarrow> (case y of Inl b \<Rightarrow> a \<sqsubseteq> b | Inr b \<Rightarrow> False) |
Inr a \<Rightarrow> (case y of Inl b \<Rightarrow> False | Inr b \<Rightarrow> a \<sqsubseteq> b)"
instance ..
end
-lemma Inl_less_iff [simp]: "Inl x \<sqsubseteq> Inl y = x \<sqsubseteq> y"
-unfolding less_sum_def by simp
+lemma Inl_below_Inl [simp]: "Inl x \<sqsubseteq> Inl y = x \<sqsubseteq> y"
+unfolding below_sum_def by simp
-lemma Inr_less_iff [simp]: "Inr x \<sqsubseteq> Inr y = x \<sqsubseteq> y"
-unfolding less_sum_def by simp
+lemma Inr_below_Inr [simp]: "Inr x \<sqsubseteq> Inr y = x \<sqsubseteq> y"
+unfolding below_sum_def by simp
-lemma Inl_less_Inr [simp]: "\<not> Inl x \<sqsubseteq> Inr y"
-unfolding less_sum_def by simp
+lemma Inl_below_Inr [simp]: "\<not> Inl x \<sqsubseteq> Inr y"
+unfolding below_sum_def by simp
-lemma Inr_less_Inl [simp]: "\<not> Inr x \<sqsubseteq> Inl y"
-unfolding less_sum_def by simp
+lemma Inr_below_Inl [simp]: "\<not> Inr x \<sqsubseteq> Inl y"
+unfolding below_sum_def by simp
lemma Inl_mono: "x \<sqsubseteq> y \<Longrightarrow> Inl x \<sqsubseteq> Inl y"
by simp
@@ -39,20 +39,20 @@
lemma Inr_mono: "x \<sqsubseteq> y \<Longrightarrow> Inr x \<sqsubseteq> Inr y"
by simp
-lemma Inl_lessE: "\<lbrakk>Inl a \<sqsubseteq> x; \<And>b. \<lbrakk>x = Inl b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
+lemma Inl_belowE: "\<lbrakk>Inl a \<sqsubseteq> x; \<And>b. \<lbrakk>x = Inl b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
by (cases x, simp_all)
-lemma Inr_lessE: "\<lbrakk>Inr a \<sqsubseteq> x; \<And>b. \<lbrakk>x = Inr b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
+lemma Inr_belowE: "\<lbrakk>Inr a \<sqsubseteq> x; \<And>b. \<lbrakk>x = Inr b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
by (cases x, simp_all)
-lemmas sum_less_elims = Inl_lessE Inr_lessE
+lemmas sum_below_elims = Inl_belowE Inr_belowE
-lemma sum_less_cases:
+lemma sum_below_cases:
"\<lbrakk>x \<sqsubseteq> y;
\<And>a b. \<lbrakk>x = Inl a; y = Inl b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R;
\<And>a b. \<lbrakk>x = Inr a; y = Inr b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk>
\<Longrightarrow> R"
-by (cases x, safe elim!: sum_less_elims, auto)
+by (cases x, safe elim!: sum_below_elims, auto)
subsection {* Sum type is a complete partial order *}
@@ -64,18 +64,18 @@
next
fix x y :: "'a + 'b"
assume "x \<sqsubseteq> y" and "y \<sqsubseteq> x" thus "x = y"
- by (induct x, auto elim!: sum_less_elims intro: antisym_less)
+ by (induct x, auto elim!: sum_below_elims intro: below_antisym)
next
fix x y z :: "'a + 'b"
assume "x \<sqsubseteq> y" and "y \<sqsubseteq> z" thus "x \<sqsubseteq> z"
- by (induct x, auto elim!: sum_less_elims intro: trans_less)
+ by (induct x, auto elim!: sum_below_elims intro: below_trans)
qed
lemma monofun_inv_Inl: "monofun (\<lambda>p. THE a. p = Inl a)"
-by (rule monofunI, erule sum_less_cases, simp_all)
+by (rule monofunI, erule sum_below_cases, simp_all)
lemma monofun_inv_Inr: "monofun (\<lambda>p. THE b. p = Inr b)"
-by (rule monofunI, erule sum_less_cases, simp_all)
+by (rule monofunI, erule sum_below_cases, simp_all)
lemma sum_chain_cases:
assumes Y: "chain Y"
@@ -87,12 +87,12 @@
apply (rule ch2ch_monofun [OF monofun_inv_Inl Y])
apply (rule ext)
apply (cut_tac j=i in chain_mono [OF Y le0], simp)
- apply (erule Inl_lessE, simp)
+ apply (erule Inl_belowE, simp)
apply (rule B)
apply (rule ch2ch_monofun [OF monofun_inv_Inr Y])
apply (rule ext)
apply (cut_tac j=i in chain_mono [OF Y le0], simp)
- apply (erule Inr_lessE, simp)
+ apply (erule Inr_belowE, simp)
done
lemma is_lub_Inl: "range S <<| x \<Longrightarrow> range (\<lambda>i. Inl (S i)) <<| Inl x"
@@ -100,7 +100,7 @@
apply (rule ub_rangeI)
apply (simp add: is_ub_lub)
apply (frule ub_rangeD [where i=arbitrary])
- apply (erule Inl_lessE, simp)
+ apply (erule Inl_belowE, simp)
apply (erule is_lub_lub)
apply (rule ub_rangeI)
apply (drule ub_rangeD, simp)
@@ -111,7 +111,7 @@
apply (rule ub_rangeI)
apply (simp add: is_ub_lub)
apply (frule ub_rangeD [where i=arbitrary])
- apply (erule Inr_lessE, simp)
+ apply (erule Inr_belowE, simp)
apply (erule is_lub_lub)
apply (rule ub_rangeI)
apply (drule ub_rangeD, simp)
@@ -130,17 +130,14 @@
subsection {* Continuity of @{term Inl}, @{term Inr}, @{term sum_case} *}
-lemma cont2cont_Inl [simp]: "cont f \<Longrightarrow> cont (\<lambda>x. Inl (f x))"
-by (fast intro: contI is_lub_Inl elim: contE)
-
-lemma cont2cont_Inr [simp]: "cont f \<Longrightarrow> cont (\<lambda>x. Inr (f x))"
-by (fast intro: contI is_lub_Inr elim: contE)
-
lemma cont_Inl: "cont Inl"
-by (rule cont2cont_Inl [OF cont_id])
+by (intro contI is_lub_Inl cpo_lubI)
lemma cont_Inr: "cont Inr"
-by (rule cont2cont_Inr [OF cont_id])
+by (intro contI is_lub_Inr cpo_lubI)
+
+lemmas cont2cont_Inl [cont2cont] = cont_compose [OF cont_Inl]
+lemmas cont2cont_Inr [cont2cont] = cont_compose [OF cont_Inr]
lemmas ch2ch_Inl [simp] = ch2ch_cont [OF cont_Inl]
lemmas ch2ch_Inr [simp] = ch2ch_cont [OF cont_Inr]
@@ -161,16 +158,33 @@
apply (simp add: cont2contlubE [OF cont_Inr, symmetric] contE)
done
-lemma cont2cont_sum_case [simp]:
+lemma cont2cont_sum_case:
assumes f1: "\<And>a. cont (\<lambda>x. f x a)" and f2: "\<And>x. cont (\<lambda>a. f x a)"
assumes g1: "\<And>b. cont (\<lambda>x. g x b)" and g2: "\<And>x. cont (\<lambda>b. g x b)"
assumes h: "cont (\<lambda>x. h x)"
shows "cont (\<lambda>x. case h x of Inl a \<Rightarrow> f x a | Inr b \<Rightarrow> g x b)"
-apply (rule cont2cont_app2 [OF cont2cont_lambda _ h])
+apply (rule cont_apply [OF h])
+apply (rule cont_sum_case2 [OF f2 g2])
apply (rule cont_sum_case1 [OF f1 g1])
-apply (rule cont_sum_case2 [OF f2 g2])
done
+lemma cont2cont_sum_case' [cont2cont]:
+ assumes f: "cont (\<lambda>p. f (fst p) (snd p))"
+ assumes g: "cont (\<lambda>p. g (fst p) (snd p))"
+ assumes h: "cont (\<lambda>x. h x)"
+ shows "cont (\<lambda>x. case h x of Inl a \<Rightarrow> f x a | Inr b \<Rightarrow> g x b)"
+proof -
+ note f1 = f [THEN cont_fst_snd_D1]
+ note f2 = f [THEN cont_fst_snd_D2]
+ note g1 = g [THEN cont_fst_snd_D1]
+ note g2 = g [THEN cont_fst_snd_D2]
+ show ?thesis
+ apply (rule cont_apply [OF h])
+ apply (rule cont_sum_case2 [OF f2 g2])
+ apply (rule cont_sum_case1 [OF f1 g1])
+ done
+qed
+
subsection {* Compactness and chain-finiteness *}
lemma compact_Inl: "compact a \<Longrightarrow> compact (Inl a)"
@@ -212,7 +226,7 @@
instance "+" :: (finite_po, finite_po) finite_po ..
instance "+" :: (discrete_cpo, discrete_cpo) discrete_cpo
-by intro_classes (simp add: less_sum_def split: sum.split)
+by intro_classes (simp add: below_sum_def split: sum.split)
subsection {* Sum type is a bifinite domain *}
--- a/src/HOLCF/Tools/adm_tac.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Tools/adm_tac.ML Mon May 11 17:20:52 2009 +0200
@@ -18,7 +18,7 @@
val adm_tac: Proof.context -> (int -> tactic) -> int -> tactic
end;
-structure Adm: ADM =
+structure Adm :> ADM =
struct
--- a/src/HOLCF/Tools/cont_consts.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Tools/cont_consts.ML Mon May 11 17:20:52 2009 +0200
@@ -8,18 +8,16 @@
signature CONT_CONSTS =
sig
- val add_consts: (bstring * string * mixfix) list -> theory -> theory
- val add_consts_i: (bstring * typ * mixfix) list -> theory -> theory
+ val add_consts: (binding * string * mixfix) list -> theory -> theory
+ val add_consts_i: (binding * typ * mixfix) list -> theory -> theory
end;
-structure ContConsts: CONT_CONSTS =
+structure ContConsts :> CONT_CONSTS =
struct
(* misc utils *)
-open HOLCFLogic;
-
fun first (x,_,_) = x;
fun second (_,x,_) = x;
fun third (_,_,x) = x;
@@ -51,29 +49,33 @@
declaration with the original name, type ...=>..., and the original mixfix
is generated and connected to the other declaration via some translation.
*)
-fun fix_mixfix (syn , T, mx as Infix p ) =
- (Syntax.const_name mx syn, T, InfixName (syn, p))
- | fix_mixfix (syn , T, mx as Infixl p ) =
- (Syntax.const_name mx syn, T, InfixlName (syn, p))
- | fix_mixfix (syn , T, mx as Infixr p ) =
- (Syntax.const_name mx syn, T, InfixrName (syn, p))
+fun const_binding mx = Binding.name o Syntax.const_name mx o Binding.name_of;
+
+fun fix_mixfix (syn , T, mx as Infix p ) =
+ (const_binding mx syn, T, InfixName (Binding.name_of syn, p))
+ | fix_mixfix (syn , T, mx as Infixl p ) =
+ (const_binding mx syn, T, InfixlName (Binding.name_of syn, p))
+ | fix_mixfix (syn , T, mx as Infixr p ) =
+ (const_binding mx syn, T, InfixrName (Binding.name_of syn, p))
| fix_mixfix decl = decl;
+
fun transform decl = let
val (c, T, mx) = fix_mixfix decl;
- val c2 = "_cont_" ^ c;
+ val c1 = Binding.name_of c;
+ val c2 = "_cont_" ^ c1;
val n = Syntax.mixfix_args mx
- in ((c , T,NoSyn),
- (c2,change_arrow n T,mx ),
- trans_rules c2 c n mx) end;
+ in ((c, T, NoSyn),
+ (Binding.name c2, change_arrow n T, mx),
+ trans_rules c2 c1 n mx) end;
-fun cfun_arity (Type(n,[_,T])) = if n = cfun_arrow then 1+cfun_arity T else 0
+fun cfun_arity (Type(n,[_,T])) = if n = @{type_name "->"} then 1+cfun_arity T else 0
| cfun_arity _ = 0;
fun is_contconst (_,_,NoSyn ) = false
| is_contconst (_,_,Binder _) = false
| is_contconst (c,T,mx ) = cfun_arity T >= Syntax.mixfix_args mx
handle ERROR msg => cat_error msg ("in mixfix annotation for " ^
- quote (Syntax.const_name mx c));
+ quote (Syntax.const_name mx (Binding.name_of c)));
(* add_consts(_i) *)
@@ -85,7 +87,7 @@
val transformed_decls = map transform contconst_decls;
in
thy
- |> (Sign.add_consts_i o map (upd_first Binding.name))
+ |> Sign.add_consts_i
(normal_decls @ map first transformed_decls @ map second transformed_decls)
|> Sign.add_trrules_i (maps third transformed_decls)
end;
@@ -100,7 +102,7 @@
val _ =
OuterSyntax.command "consts" "declare constants (HOLCF)" K.thy_decl
- (Scan.repeat1 P.const >> (Toplevel.theory o add_consts));
+ (Scan.repeat1 P.const_binding >> (Toplevel.theory o add_consts));
end;
--- a/src/HOLCF/Tools/cont_proc.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Tools/cont_proc.ML Mon May 11 17:20:52 2009 +0200
@@ -12,7 +12,7 @@
val setup: theory -> theory
end;
-structure ContProc: CONT_PROC =
+structure ContProc :> CONT_PROC =
struct
(** theory context references **)
--- a/src/HOLCF/Tools/domain/domain_axioms.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Tools/domain/domain_axioms.ML Mon May 11 17:20:52 2009 +0200
@@ -4,7 +4,14 @@
Syntax generator for domain command.
*)
-structure Domain_Axioms = struct
+signature DOMAIN_AXIOMS =
+sig
+ val add_axioms : bstring -> Domain_Library.eq list -> theory -> theory
+end;
+
+
+structure Domain_Axioms :> DOMAIN_AXIOMS =
+struct
local
@@ -60,14 +67,18 @@
(if con'=con then TT else FF) args)) cons))
in map ddef cons end;
- val mat_defs = let
- fun mdef (con,_) = (mat_name con ^"_def",%%:(mat_name con) ==
- list_ccomb(%%:(dname^"_when"),map
- (fn (con',args) => (List.foldr /\#
- (if con'=con
- then mk_return (mk_ctuple (map (bound_arg args) args))
- else mk_fail) args)) cons))
- in map mdef cons end;
+ val mat_defs =
+ let
+ fun mdef (con,_) =
+ let
+ val k = Bound 0
+ val x = Bound 1
+ fun one_con (con', args') =
+ if con'=con then k else List.foldr /\# mk_fail args'
+ val w = list_ccomb(%%:(dname^"_when"), map one_con cons)
+ val rhs = /\ "x" (/\ "k" (w ` x))
+ in (mat_name con ^"_def", %%:(mat_name con) == rhs) end
+ in map mdef cons end;
val pat_defs =
let
@@ -135,7 +146,7 @@
in (* local *)
-fun add_axioms (comp_dnam, eqs : eq list) thy' = let
+fun add_axioms comp_dnam (eqs : eq list) thy' = let
val comp_dname = Sign.full_bname thy' comp_dnam;
val dnames = map (fst o fst) eqs;
val x_name = idx_name dnames "x";
--- a/src/HOLCF/Tools/domain/domain_extender.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Tools/domain/domain_extender.ML Mon May 11 17:20:52 2009 +0200
@@ -1,55 +1,40 @@
(* Title: HOLCF/Tools/domain/domain_extender.ML
- ID: $Id$
Author: David von Oheimb
Theory extender for domain command, including theory syntax.
-
-###TODO:
-
-this definition
-domain empty = silly empty
-yields
-Exception-
- TERM
- ("typ_of_term: bad encoding of type",
- [Abs ("uu", "_", Const ("NONE", "_"))]) raised
-but this works fine:
-domain Empty = silly Empty
-
-strange syntax errors are produced for:
-domain xx = xx ("x yy")
-domain 'a foo = foo (sel::"'a")
-and bar = bar ("'a dummy")
-
*)
signature DOMAIN_EXTENDER =
sig
- val add_domain: string * ((bstring * string list) *
- (string * mixfix * (bool * string option * string) list) list) list
+ val add_domain_cmd: string -> (string list * binding * mixfix *
+ (binding * (bool * binding option * string) list * mixfix) list) list
-> theory -> theory
- val add_domain_i: string * ((bstring * string list) *
- (string * mixfix * (bool * string option * typ) list) list) list
+ val add_domain: string -> (string list * binding * mixfix *
+ (binding * (bool * binding option * typ) list * mixfix) list) list
-> theory -> theory
end;
-structure Domain_Extender: DOMAIN_EXTENDER =
+structure Domain_Extender :> DOMAIN_EXTENDER =
struct
open Domain_Library;
(* ----- general testing and preprocessing of constructor list -------------- *)
-fun check_and_sort_domain (dtnvs: (string * typ list) list,
- cons'' : ((string * mixfix * (bool * string option * typ) list) list) list) sg =
+fun check_and_sort_domain
+ (dtnvs : (string * typ list) list)
+ (cons'' : ((binding * (bool * binding option * typ) list * mixfix) list) list)
+ (sg : theory)
+ : ((string * typ list) *
+ (binding * (bool * binding option * typ) list * mixfix) list) list =
let
val defaultS = Sign.defaultS sg;
val test_dupl_typs = (case duplicates (op =) (map fst dtnvs) of
[] => false | dups => error ("Duplicate types: " ^ commas_quote dups));
- val test_dupl_cons = (case duplicates (op =) (map first (List.concat cons'')) of
+ val test_dupl_cons = (case duplicates (op =) (map (Binding.name_of o first) (List.concat cons'')) of
[] => false | dups => error ("Duplicate constructors: "
^ commas_quote dups));
- val test_dupl_sels = (case duplicates (op =) (List.mapPartial second
- (List.concat (map third (List.concat cons'')))) of
+ val test_dupl_sels = (case duplicates (op =) (map Binding.name_of (List.mapPartial second
+ (List.concat (map second (List.concat cons''))))) of
[] => false | dups => error("Duplicate selectors: "^commas_quote dups));
val test_dupl_tvars = exists(fn s=>case duplicates (op =) (map(fst o dest_TFree)s)of
[] => false | dups => error("Duplicate type arguments: "
@@ -90,26 +75,31 @@
| analyse indirect (TVar _) = Imposs "extender:analyse";
fun check_pcpo T = if pcpo_type sg T then T
else error("Constructor argument type is not of sort pcpo: "^string_of_typ sg T);
- val analyse_con = upd_third (map (upd_third (check_pcpo o analyse false)));
+ val analyse_con = upd_second (map (upd_third (check_pcpo o analyse false)));
in ((dname,distinct_typevars), map analyse_con cons') end;
in ListPair.map analyse_equation (dtnvs,cons'')
end; (* let *)
(* ----- calls for building new thy and thms -------------------------------- *)
-fun gen_add_domain prep_typ (comp_dnam, eqs''') thy''' =
+fun gen_add_domain
+ (prep_typ : theory -> 'a -> typ)
+ (comp_dnam : string)
+ (eqs''' : (string list * binding * mixfix *
+ (binding * (bool * binding option * 'a) list * mixfix) list) list)
+ (thy''' : theory) =
let
- val dtnvs = map ((fn (dname,vs) =>
- (Sign.full_bname thy''' dname, map (Syntax.read_typ_global thy''') vs))
- o fst) eqs''';
- val cons''' = map snd eqs''';
- fun thy_type (dname,tvars) = (Binding.name (Long_Name.base_name dname), length tvars, NoSyn);
- fun thy_arity (dname,tvars) = (dname, map (snd o dest_TFree) tvars, pcpoS);
- val thy'' = thy''' |> Sign.add_types (map thy_type dtnvs)
+ val dtnvs = map (fn (vs,dname:binding,mx,_) =>
+ (dname, map (Syntax.read_typ_global thy''') vs, mx)) eqs''';
+ val cons''' = map (fn (_,_,_,cons) => cons) eqs''';
+ fun thy_type (dname,tvars,mx) = (dname, length tvars, mx);
+ fun thy_arity (dname,tvars,mx) = (Sign.full_name thy''' dname, map (snd o dest_TFree) tvars, pcpoS);
+ val thy'' = thy''' |> Sign.add_types (map thy_type dtnvs)
|> fold (AxClass.axiomatize_arity o thy_arity) dtnvs;
- val cons'' = map (map (upd_third (map (upd_third (prep_typ thy''))))) cons''';
- val eqs' = check_and_sort_domain (dtnvs,cons'') thy'';
- val thy' = thy'' |> Domain_Syntax.add_syntax (comp_dnam,eqs');
+ val cons'' = map (map (upd_second (map (upd_third (prep_typ thy''))))) cons''';
+ val dtnvs' = map (fn (dname,vs,mx) => (Sign.full_name thy''' dname,vs)) dtnvs;
+ val eqs' : ((string * typ list) * (binding * (bool * binding option * typ) list * mixfix) list) list = check_and_sort_domain dtnvs' cons'' thy'';
+ val thy' = thy'' |> Domain_Syntax.add_syntax comp_dnam eqs';
val dts = map (Type o fst) eqs';
val new_dts = map (fn ((s,Ts),_) => (s, map (fst o dest_TFree) Ts)) eqs';
fun strip ss = Library.drop (find_index_eq "'" ss +1, ss);
@@ -118,16 +108,16 @@
in if Symbol.is_letter c then c else "t" end
| typid (TFree (id,_) ) = hd (strip (tl (Symbol.explode id)))
| typid (TVar ((id,_),_)) = hd (tl (Symbol.explode id));
- fun one_con (con,mx,args) =
- ((Syntax.const_name mx con),
+ fun one_con (con,args,mx) =
+ ((Syntax.const_name mx (Binding.name_of con)),
ListPair.map (fn ((lazy,sel,tp),vn) => ((lazy,
find_index_eq tp dts,
DatatypeAux.dtyp_of_typ new_dts tp),
- sel,vn))
+ Option.map Binding.name_of sel,vn))
(args,(mk_var_names(map (typid o third) args)))
) : cons;
val eqs = map (fn (dtnvs,cons') => (dtnvs, map one_con cons')) eqs' : eq list;
- val thy = thy' |> Domain_Axioms.add_axioms (comp_dnam,eqs);
+ val thy = thy' |> Domain_Axioms.add_axioms comp_dnam eqs;
val ((rewss, take_rews), theorems_thy) = thy |> fold_map (fn eq =>
Domain_Theorems.theorems (eq, eqs)) eqs
||>> Domain_Theorems.comp_theorems (comp_dnam, eqs);
@@ -138,8 +128,8 @@
|> Sign.parent_path
end;
-val add_domain_i = gen_add_domain Sign.certify_typ;
-val add_domain = gen_add_domain Syntax.read_typ_global;
+val add_domain = gen_add_domain Sign.certify_typ;
+val add_domain_cmd = gen_add_domain Syntax.read_typ_global;
(** outer syntax **)
@@ -148,33 +138,47 @@
val _ = OuterKeyword.keyword "lazy";
-val dest_decl =
+val dest_decl : (bool * binding option * string) parser =
P.$$$ "(" |-- Scan.optional (P.$$$ "lazy" >> K true) false --
- (P.name >> SOME) -- (P.$$$ "::" |-- P.typ) --| P.$$$ ")" >> P.triple1
+ (P.binding >> SOME) -- (P.$$$ "::" |-- P.typ) --| P.$$$ ")" >> P.triple1
|| P.$$$ "(" |-- P.$$$ "lazy" |-- P.typ --| P.$$$ ")"
>> (fn t => (true,NONE,t))
|| P.typ >> (fn t => (false,NONE,t));
val cons_decl =
- P.name -- Scan.repeat dest_decl -- P.opt_mixfix
- >> (fn ((c, ds), mx) => (c, mx, ds));
+ P.binding -- Scan.repeat dest_decl -- P.opt_mixfix;
+
+val type_var' =
+ (P.type_ident ^^ Scan.optional (P.$$$ "::" ^^ P.!!! P.sort) "");
+
+val type_args' =
+ type_var' >> single ||
+ P.$$$ "(" |-- P.!!! (P.list1 type_var' --| P.$$$ ")") ||
+ Scan.succeed [];
+
+val domain_decl =
+ (type_args' -- P.binding -- P.opt_infix) --
+ (P.$$$ "=" |-- P.enum1 "|" cons_decl);
-val type_var' = (P.type_ident ^^
- Scan.optional (P.$$$ "::" ^^ P.!!! P.sort) "");
-val type_args' = type_var' >> single ||
- P.$$$ "(" |-- P.!!! (P.list1 type_var' --| P.$$$ ")") ||
- Scan.succeed [];
+val domains_decl =
+ Scan.option (P.$$$ "(" |-- P.name --| P.$$$ ")") --
+ P.and_list1 domain_decl;
-val domain_decl = (type_args' -- P.name >> Library.swap) --
- (P.$$$ "=" |-- P.enum1 "|" cons_decl);
-val domains_decl =
- Scan.option (P.$$$ "(" |-- P.name --| P.$$$ ")") -- P.and_list1 domain_decl
- >> (fn (opt_name, doms) =>
- (case opt_name of NONE => space_implode "_" (map (#1 o #1) doms) | SOME s => s, doms));
+fun mk_domain (opt_name : string option, doms : (((string list * binding) * mixfix) *
+ ((binding * (bool * binding option * string) list) * mixfix) list) list ) =
+ let
+ val names = map (fn (((_, t), _), _) => Binding.name_of t) doms;
+ val specs : (string list * binding * mixfix *
+ (binding * (bool * binding option * string) list * mixfix) list) list =
+ map (fn (((vs, t), mx), cons) =>
+ (vs, t, mx, map (fn ((c, ds), mx) => (c, ds, mx)) cons)) doms;
+ val comp_dnam =
+ case opt_name of NONE => space_implode "_" names | SOME s => s;
+ in add_domain_cmd comp_dnam specs end;
val _ =
OuterSyntax.command "domain" "define recursive domains (HOLCF)" K.thy_decl
- (domains_decl >> (Toplevel.theory o add_domain));
+ (domains_decl >> (Toplevel.theory o mk_domain));
end;
--- a/src/HOLCF/Tools/domain/domain_library.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Tools/domain/domain_library.ML Mon May 11 17:20:52 2009 +0200
@@ -30,11 +30,129 @@
| _ => [thm];
in map zero_var_indexes (at thm) end;
+(* infix syntax *)
+
+infixr 5 -->;
+infixr 6 ->>;
+infixr 0 ===>;
+infixr 0 ==>;
+infix 0 ==;
+infix 1 ===;
+infix 1 ~=;
+infix 1 <<;
+infix 1 ~<<;
+
+infix 9 ` ;
+infix 9 `% ;
+infix 9 `%%;
+
+
(* ----- specific support for domain ---------------------------------------- *)
-structure Domain_Library = struct
+signature DOMAIN_LIBRARY =
+sig
+ val Imposs : string -> 'a;
+ val pcpo_type : theory -> typ -> bool;
+ val string_of_typ : theory -> typ -> string;
+
+ (* Creating HOLCF types *)
+ val mk_cfunT : typ * typ -> typ;
+ val ->> : typ * typ -> typ;
+ val mk_ssumT : typ * typ -> typ;
+ val mk_sprodT : typ * typ -> typ;
+ val mk_uT : typ -> typ;
+ val oneT : typ;
+ val trT : typ;
+ val mk_maybeT : typ -> typ;
+ val mk_ctupleT : typ list -> typ;
+ val mk_TFree : string -> typ;
+ val pcpoS : sort;
+
+ (* Creating HOLCF terms *)
+ val %: : string -> term;
+ val %%: : string -> term;
+ val ` : term * term -> term;
+ val `% : term * string -> term;
+ val /\ : string -> term -> term;
+ val UU : term;
+ val TT : term;
+ val FF : term;
+ val mk_up : term -> term;
+ val mk_sinl : term -> term;
+ val mk_sinr : term -> term;
+ val mk_stuple : term list -> term;
+ val mk_ctuple : term list -> term;
+ val mk_fix : term -> term;
+ val mk_iterate : term * term * term -> term;
+ val mk_fail : term;
+ val mk_return : term -> term;
+ val cproj : term -> 'a list -> int -> term;
+ val list_ccomb : term * term list -> term;
+ val con_app : string -> ('a * 'b * string) list -> term;
+ val con_app2 : string -> ('a -> term) -> 'a list -> term;
+ val proj : term -> 'a list -> int -> term;
+ val prj : ('a -> 'b -> 'a) -> ('a -> 'b -> 'a) -> 'a -> 'b list -> int -> 'a;
+ val mk_ctuple_pat : term list -> term;
+ val mk_branch : term -> term;
-open HOLCFLogic;
+ (* Creating propositions *)
+ val mk_conj : term * term -> term;
+ val mk_disj : term * term -> term;
+ val mk_imp : term * term -> term;
+ val mk_lam : string * term -> term;
+ val mk_all : string * term -> term;
+ val mk_ex : string * term -> term;
+ val mk_constrain : typ * term -> term;
+ val mk_constrainall : string * typ * term -> term;
+ val === : term * term -> term;
+ val << : term * term -> term;
+ val ~<< : term * term -> term;
+ val strict : term -> term;
+ val defined : term -> term;
+ val mk_adm : term -> term;
+ val mk_compact : term -> term;
+ val lift : ('a -> term) -> 'a list * term -> term;
+ val lift_defined : ('a -> term) -> 'a list * term -> term;
+
+ (* Creating meta-propositions *)
+ val mk_trp : term -> term; (* HOLogic.mk_Trueprop *)
+ val == : term * term -> term;
+ val ===> : term * term -> term;
+ val ==> : term * term -> term;
+ val mk_All : string * term -> term;
+
+ (* Domain specifications *)
+ type arg = (bool * int * DatatypeAux.dtyp) * string option * string;
+ type cons = string * arg list;
+ type eq = (string * typ list) * cons list;
+ val is_lazy : arg -> bool;
+ val rec_of : arg -> int;
+ val sel_of : arg -> string option;
+ val vname : arg -> string;
+ val upd_vname : (string -> string) -> arg -> arg;
+ val is_rec : arg -> bool;
+ val is_nonlazy_rec : arg -> bool;
+ val nonlazy : arg list -> string list;
+ val nonlazy_rec : arg list -> string list;
+ val %# : arg -> term;
+ val /\# : arg * term -> term;
+ val when_body : cons list -> (int * int -> term) -> term;
+ val when_funs : 'a list -> string list;
+ val bound_arg : ''a list -> ''a -> term; (* ''a = arg or string *)
+ val idx_name : 'a list -> string -> int -> string;
+ val app_rec_arg : (int -> term) -> arg -> term;
+
+ (* Name mangling *)
+ val strip_esc : string -> string;
+ val extern_name : string -> string;
+ val dis_name : string -> string;
+ val mat_name : string -> string;
+ val pat_name : string -> string;
+ val mk_var_names : string list -> string list;
+end;
+
+structure Domain_Library :> DOMAIN_LIBRARY =
+struct
exception Impossible of string;
fun Imposs msg = raise Impossible ("Domain:"^msg);
@@ -72,19 +190,24 @@
| index_vnames([],occupied) = [];
in index_vnames(map nonreserved ids, [("O",0),("o",0)]) end;
-fun pcpo_type sg t = Sign.of_sort sg (Sign.certify_typ sg t, pcpoS);
+fun pcpo_type sg t = Sign.of_sort sg (Sign.certify_typ sg t, @{sort pcpo});
fun string_of_typ sg = Syntax.string_of_typ_global sg o Sign.certify_typ sg;
(* ----- constructor list handling ----- *)
-type cons = (string * (* operator name of constr *)
- ((bool*int*DatatypeAux.dtyp)* (* (lazy,recursive element or ~1) *)
- string option* (* selector name *)
- string) (* argument name *)
- list); (* argument list *)
-type eq = (string * (* name of abstracted type *)
- typ list) * (* arguments of abstracted type *)
- cons list; (* represented type, as a constructor list *)
+type arg =
+ (bool * int * DatatypeAux.dtyp) * (* (lazy,recursive element or ~1) *)
+ string option * (* selector name *)
+ string; (* argument name *)
+
+type cons =
+ string * (* operator name of constr *)
+ arg list; (* argument list *)
+
+type eq =
+ (string * (* name of abstracted type *)
+ typ list) * (* arguments of abstracted type *)
+ cons list; (* represented type, as a constructor list *)
fun rec_of arg = second (first arg);
fun is_lazy arg = first (first arg);
@@ -98,7 +221,16 @@
(* ----- support for type and mixfix expressions ----- *)
-infixr 5 -->;
+fun mk_uT T = Type(@{type_name "u"}, [T]);
+fun mk_cfunT (T, U) = Type(@{type_name "->"}, [T, U]);
+fun mk_sprodT (T, U) = Type(@{type_name "**"}, [T, U]);
+fun mk_ssumT (T, U) = Type(@{type_name "++"}, [T, U]);
+val oneT = @{typ one};
+val trT = @{typ tr};
+
+val op ->> = mk_cfunT;
+
+fun mk_TFree s = TFree ("'" ^ s, @{sort pcpo});
(* ----- support for term expressions ----- *)
@@ -125,7 +257,7 @@
infix 0 ==; fun S == T = %%:"==" $ S $ T;
infix 1 ===; fun S === T = %%:"op =" $ S $ T;
infix 1 ~=; fun S ~= T = HOLogic.mk_not (S === T);
-infix 1 <<; fun S << T = %%: @{const_name Porder.sq_le} $ S $ T;
+infix 1 <<; fun S << T = %%: @{const_name Porder.below} $ S $ T;
infix 1 ~<<; fun S ~<< T = HOLogic.mk_not (S << T);
infix 9 ` ; fun f ` x = %%: @{const_name Rep_CFun} $ f $ x;
--- a/src/HOLCF/Tools/domain/domain_syntax.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Tools/domain/domain_syntax.ML Mon May 11 17:20:52 2009 +0200
@@ -4,32 +4,42 @@
Syntax generator for domain command.
*)
-structure Domain_Syntax = struct
+signature DOMAIN_SYNTAX =
+sig
+ val add_syntax: string -> ((string * typ list) *
+ (binding * (bool * binding option * typ) list * mixfix) list) list
+ -> theory -> theory
+end;
+
+
+structure Domain_Syntax :> DOMAIN_SYNTAX =
+struct
local
open Domain_Library;
infixr 5 -->; infixr 6 ->>;
fun calc_syntax dtypeprod ((dname, typevars),
- (cons': (string * mixfix * (bool * string option * typ) list) list)) =
+ (cons': (binding * (bool * binding option * typ) list * mixfix) list)) : ((binding * typ * mixfix) list * ast Syntax.trrule list) =
let
(* ----- constants concerning the isomorphism ------------------------------- *)
local
fun opt_lazy (lazy,_,t) = if lazy then mk_uT t else t
- fun prod (_,_,args) = if args = [] then oneT
- else foldr1 mk_sprodT (map opt_lazy args);
+ fun prod (_,args,_) = case args of [] => oneT
+ | _ => foldr1 mk_sprodT (map opt_lazy args);
fun freetvar s = let val tvar = mk_TFree s in
if tvar mem typevars then freetvar ("t"^s) else tvar end;
- fun when_type (_ ,_,args) = List.foldr (op ->>) (freetvar "t") (map third args);
+ fun when_type (_,args,_) = List.foldr (op ->>) (freetvar "t") (map third args);
in
val dtype = Type(dname,typevars);
val dtype2 = foldr1 mk_ssumT (map prod cons');
val dnam = Long_Name.base_name dname;
- val const_rep = (dnam^"_rep" , dtype ->> dtype2, NoSyn);
- val const_abs = (dnam^"_abs" , dtype2 ->> dtype , NoSyn);
- val const_when = (dnam^"_when", List.foldr (op ->>) (dtype ->> freetvar "t") (map when_type cons'), NoSyn);
- val const_copy = (dnam^"_copy", dtypeprod ->> dtype ->> dtype , NoSyn);
+ fun dbind s = Binding.name (dnam ^ s);
+ val const_rep = (dbind "_rep" , dtype ->> dtype2, NoSyn);
+ val const_abs = (dbind "_abs" , dtype2 ->> dtype , NoSyn);
+ val const_when = (dbind "_when", List.foldr (op ->>) (dtype ->> freetvar "t") (map when_type cons'), NoSyn);
+ val const_copy = (dbind "_copy", dtypeprod ->> dtype ->> dtype , NoSyn);
end;
(* ----- constants concerning constructors, discriminators, and selectors --- *)
@@ -40,23 +50,28 @@
else c::esc cs
| esc [] = []
in implode o esc o Symbol.explode end;
- fun con (name,s,args) = (name, List.foldr (op ->>) dtype (map third args),s);
- fun dis (con ,s,_ ) = (dis_name_ con, dtype->>trT,
- Mixfix(escape ("is_" ^ con), [], Syntax.max_pri));
+ fun dis_name_ con = Binding.name ("is_" ^ strip_esc (Binding.name_of con));
+ fun mat_name_ con = Binding.name ("match_" ^ strip_esc (Binding.name_of con));
+ fun pat_name_ con = Binding.name (strip_esc (Binding.name_of con) ^ "_pat");
+ fun con (name,args,mx) = (name, List.foldr (op ->>) dtype (map third args), mx);
+ fun dis (con,args,mx) = (dis_name_ con, dtype->>trT,
+ Mixfix(escape ("is_" ^ Binding.name_of con), [], Syntax.max_pri));
(* strictly speaking, these constants have one argument,
but the mixfix (without arguments) is introduced only
to generate parse rules for non-alphanumeric names*)
- fun mat (con ,s,args) = (mat_name_ con, dtype->>mk_maybeT(mk_ctupleT(map third args)),
- Mixfix(escape ("match_" ^ con), [], Syntax.max_pri));
- fun sel1 (_,sel,typ) = Option.map (fn s => (s,dtype ->> typ,NoSyn)) sel;
- fun sel (_ ,_,args) = List.mapPartial sel1 args;
fun freetvar s n = let val tvar = mk_TFree (s ^ string_of_int n) in
if tvar mem typevars then freetvar ("t"^s) n else tvar end;
+ fun mk_matT (a,bs,c) = a ->> foldr (op ->>) (mk_maybeT c) bs ->> mk_maybeT c;
+ fun mat (con,args,mx) = (mat_name_ con,
+ mk_matT(dtype, map third args, freetvar "t" 1),
+ Mixfix(escape ("match_" ^ Binding.name_of con), [], Syntax.max_pri));
+ fun sel1 (_,sel,typ) = Option.map (fn s => (s,dtype ->> typ,NoSyn)) sel;
+ fun sel (con,args,mx) = List.mapPartial sel1 args;
fun mk_patT (a,b) = a ->> mk_maybeT b;
fun pat_arg_typ n arg = mk_patT (third arg, freetvar "t" n);
- fun pat (con ,s,args) = (pat_name_ con, (mapn pat_arg_typ 1 args) --->
+ fun pat (con,args,mx) = (pat_name_ con, (mapn pat_arg_typ 1 args) --->
mk_patT (dtype, mk_ctupleT (map (freetvar "t") (1 upto length args))),
- Mixfix(escape (con ^ "_pat"), [], Syntax.max_pri));
+ Mixfix(escape (Binding.name_of con ^ "_pat"), [], Syntax.max_pri));
in
val consts_con = map con cons';
@@ -68,14 +83,14 @@
(* ----- constants concerning induction ------------------------------------- *)
- val const_take = (dnam^"_take" , HOLogic.natT-->dtype->>dtype, NoSyn);
- val const_finite = (dnam^"_finite", dtype-->HOLogic.boolT , NoSyn);
+ val const_take = (dbind "_take" , HOLogic.natT-->dtype->>dtype, NoSyn);
+ val const_finite = (dbind "_finite", dtype-->HOLogic.boolT , NoSyn);
(* ----- case translation --------------------------------------------------- *)
local open Syntax in
local
- fun c_ast con mx = Constant (Syntax.const_name mx con);
+ fun c_ast con mx = Constant (Syntax.const_name mx (Binding.name_of con));
fun expvar n = Variable ("e"^(string_of_int n));
fun argvar n m _ = Variable ("a"^(string_of_int n)^"_"^
(string_of_int m));
@@ -83,9 +98,9 @@
fun app s (l,r) = mk_appl (Constant s) [l,r];
val cabs = app "_cabs";
val capp = app "Rep_CFun";
- fun con1 n (con,mx,args) = Library.foldl capp (c_ast con mx, argvars n args);
- fun case1 n (con,mx,args) = app "_case1" (con1 n (con,mx,args), expvar n);
- fun arg1 n (con,_,args) = List.foldr cabs (expvar n) (argvars n args);
+ fun con1 n (con,args,mx) = Library.foldl capp (c_ast con mx, argvars n args);
+ fun case1 n (con,args,mx) = app "_case1" (con1 n (con,args,mx), expvar n);
+ fun arg1 n (con,args,_) = List.foldr cabs (expvar n) (argvars n args);
fun when1 n m = if n = m then arg1 n else K (Constant "UU");
fun app_var x = mk_appl (Constant "_variable") [x, Variable "rhs"];
@@ -101,10 +116,10 @@
(cabs (con1 n (con,mx,args), expvar n),
Library.foldl capp (Constant (dnam^"_when"), mapn (when1 n) 1 cons'))) 1 cons';
- val Case_trans = List.concat (map (fn (con,mx,args) =>
+ val Case_trans = List.concat (map (fn (con,args,mx) =>
let
val cname = c_ast con mx;
- val pname = Constant (pat_name_ con);
+ val pname = Constant (strip_esc (Binding.name_of con) ^ "_pat");
val ns = 1 upto length args;
val xs = map (fn n => Variable ("x"^(string_of_int n))) ns;
val ps = map (fn n => Variable ("p"^(string_of_int n))) ns;
@@ -130,16 +145,19 @@
in (* local *)
-fun add_syntax (comp_dnam,eqs': ((string * typ list) *
- (string * mixfix * (bool * string option * typ) list) list) list) thy'' =
+fun add_syntax
+ (comp_dnam : string)
+ (eqs' : ((string * typ list) *
+ (binding * (bool * binding option * typ) list * mixfix) list) list)
+ (thy'' : theory) =
let
val dtypes = map (Type o fst) eqs';
val boolT = HOLogic.boolT;
val funprod = foldr1 HOLogic.mk_prodT (map (fn tp => tp ->> tp ) dtypes);
val relprod = foldr1 HOLogic.mk_prodT (map (fn tp => tp --> tp --> boolT) dtypes);
- val const_copy = (comp_dnam^"_copy" ,funprod ->> funprod, NoSyn);
- val const_bisim = (comp_dnam^"_bisim" ,relprod --> boolT , NoSyn);
- val ctt = map (calc_syntax funprod) eqs';
+ val const_copy = (Binding.name (comp_dnam^"_copy"), funprod ->> funprod, NoSyn);
+ val const_bisim = (Binding.name (comp_dnam^"_bisim"), relprod --> boolT, NoSyn);
+ val ctt : ((binding * typ * mixfix) list * ast Syntax.trrule list) list = map (calc_syntax funprod) eqs';
in thy'' |> ContConsts.add_consts_i (List.concat (map fst ctt) @
(if length eqs'>1 then [const_copy] else[])@
[const_bisim])
--- a/src/HOLCF/Tools/domain/domain_theorems.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Tools/domain/domain_theorems.ML Mon May 11 17:20:52 2009 +0200
@@ -8,7 +8,14 @@
val HOLCF_ss = @{simpset};
-structure Domain_Theorems = struct
+signature DOMAIN_THEOREMS =
+sig
+ val theorems: Domain_Library.eq * Domain_Library.eq list -> theory -> thm list * theory;
+ val comp_theorems: bstring * Domain_Library.eq list -> theory -> thm list * theory;
+end;
+
+structure Domain_Theorems :> DOMAIN_THEOREMS =
+struct
val quiet_mode = ref false;
val trace_domain = ref false;
@@ -22,7 +29,7 @@
val adm_all = @{thm adm_all};
val adm_conj = @{thm adm_conj};
val adm_subst = @{thm adm_subst};
-val antisym_less_inverse = @{thm antisym_less_inverse};
+val antisym_less_inverse = @{thm below_antisym_inverse};
val beta_cfun = @{thm beta_cfun};
val cfun_arg_cong = @{thm cfun_arg_cong};
val ch2ch_Rep_CFunL = @{thm ch2ch_Rep_CFunL};
@@ -37,12 +44,12 @@
val contlub_cfun_fun = @{thm contlub_cfun_fun};
val fix_def2 = @{thm fix_def2};
val injection_eq = @{thm injection_eq};
-val injection_less = @{thm injection_less};
+val injection_less = @{thm injection_below};
val lub_equal = @{thm lub_equal};
val monofun_cfun_arg = @{thm monofun_cfun_arg};
val retraction_strict = @{thm retraction_strict};
val spair_eq = @{thm spair_eq};
-val spair_less = @{thm spair_less};
+val spair_less = @{thm spair_below};
val sscase1 = @{thm sscase1};
val ssplit1 = @{thm ssplit1};
val strictify1 = @{thm strictify1};
@@ -114,7 +121,7 @@
val all2E = @{lemma "!x y . P x y ==> (P x y ==> R) ==> R" by simp}
-val dist_eqI = @{lemma "!!x::'a::po. ~ x << y ==> x ~= y" by (blast dest!: antisym_less_inverse)}
+val dist_eqI = @{lemma "!!x::'a::po. ~ x << y ==> x ~= y" by (blast dest!: below_antisym_inverse)}
in
@@ -314,8 +321,8 @@
local
fun mat_strict (con, _) =
let
- val goal = mk_trp (strict (%%:(mat_name con)));
- val tacs = [rtac when_strict 1];
+ val goal = mk_trp (%%:(mat_name con) ` UU ` %:"rhs" === UU);
+ val tacs = [asm_simp_tac (HOLCF_ss addsimps [when_strict]) 1];
in pg axs_mat_def goal (K tacs) end;
val _ = trace " Proving mat_stricts...";
@@ -323,10 +330,10 @@
fun one_mat c (con, args) =
let
- val lhs = %%:(mat_name c) ` con_app con args;
+ val lhs = %%:(mat_name c) ` con_app con args ` %:"rhs";
val rhs =
if con = c
- then mk_return (mk_ctuple (map %# args))
+ then list_ccomb (%:"rhs", map %# args)
else mk_fail;
val goal = lift_defined %: (nonlazy args, mk_trp (lhs === rhs));
val tacs = [asm_simp_tac (HOLCF_ss addsimps when_rews) 1];
@@ -374,30 +381,32 @@
end;
local
- val rev_contrapos = @{thm rev_contrapos};
fun con_strict (con, args) =
let
+ val rules = abs_strict :: @{thms con_strict_rules};
fun one_strict vn =
let
fun f arg = if vname arg = vn then UU else %# arg;
val goal = mk_trp (con_app2 con f args === UU);
- val tacs = [asm_simp_tac (HOLCF_ss addsimps [abs_strict]) 1];
+ val tacs = [simp_tac (HOL_basic_ss addsimps rules) 1];
in pg con_appls goal (K tacs) end;
in map one_strict (nonlazy args) end;
fun con_defin (con, args) =
let
- val concl = mk_trp (defined (con_app con args));
- val goal = lift_defined %: (nonlazy args, concl);
- fun tacs ctxt = [
- rtac @{thm rev_contrapos} 1,
- eres_inst_tac ctxt [(("f", 0), dis_name con)] cfun_arg_cong 1,
- asm_simp_tac (HOLCF_ss addsimps dis_rews) 1];
- in pg [] goal tacs end;
+ fun iff_disj (t, []) = HOLogic.mk_not t
+ | iff_disj (t, ts) = t === foldr1 HOLogic.mk_disj ts;
+ val lhs = con_app con args === UU;
+ val rhss = map (fn x => %:x === UU) (nonlazy args);
+ val goal = mk_trp (iff_disj (lhs, rhss));
+ val rule1 = iso_locale RS @{thm iso.abs_defined_iff};
+ val rules = rule1 :: @{thms con_defined_iff_rules};
+ val tacs = [simp_tac (HOL_ss addsimps rules) 1];
+ in pg con_appls goal (K tacs) end;
in
val _ = trace " Proving con_stricts...";
val con_stricts = maps con_strict cons;
- val _ = trace " Proving pat_defins...";
+ val _ = trace " Proving con_defins...";
val con_defins = map con_defin cons;
val con_rews = con_stricts @ con_defins;
end;
@@ -488,7 +497,6 @@
end;
val sel_rews = sel_stricts @ sel_defins @ sel_apps;
-val rev_contrapos = @{thm rev_contrapos};
val _ = trace " Proving dist_les...";
val distincts_le =
@@ -607,23 +615,22 @@
in
thy
|> Sign.add_path (Long_Name.base_name dname)
- |> (snd o PureThy.add_thmss [
- ((Binding.name "iso_rews" , iso_rews ), [Simplifier.simp_add]),
- ((Binding.name "exhaust" , [exhaust] ), []),
- ((Binding.name "casedist" , [casedist]), [Induct.cases_type dname]),
- ((Binding.name "when_rews", when_rews ), [Simplifier.simp_add]),
- ((Binding.name "compacts", con_compacts), [Simplifier.simp_add]),
- ((Binding.name "con_rews", con_rews), [Simplifier.simp_add]),
- ((Binding.name "sel_rews", sel_rews), [Simplifier.simp_add]),
- ((Binding.name "dis_rews", dis_rews), [Simplifier.simp_add]),
- ((Binding.name "pat_rews", pat_rews), [Simplifier.simp_add]),
- ((Binding.name "dist_les", dist_les), [Simplifier.simp_add]),
- ((Binding.name "dist_eqs", dist_eqs), [Simplifier.simp_add]),
- ((Binding.name "inverts" , inverts ), [Simplifier.simp_add]),
- ((Binding.name "injects" , injects ), [Simplifier.simp_add]),
- ((Binding.name "copy_rews", copy_rews), [Simplifier.simp_add]),
- ((Binding.name "match_rews", mat_rews), [Simplifier.simp_add])
- ])
+ |> snd o PureThy.add_thmss [
+ ((Binding.name "iso_rews" , iso_rews ), [Simplifier.simp_add]),
+ ((Binding.name "exhaust" , [exhaust] ), []),
+ ((Binding.name "casedist" , [casedist] ), [Induct.cases_type dname]),
+ ((Binding.name "when_rews" , when_rews ), [Simplifier.simp_add]),
+ ((Binding.name "compacts" , con_compacts), [Simplifier.simp_add]),
+ ((Binding.name "con_rews" , con_rews ), [Simplifier.simp_add]),
+ ((Binding.name "sel_rews" , sel_rews ), [Simplifier.simp_add]),
+ ((Binding.name "dis_rews" , dis_rews ), [Simplifier.simp_add]),
+ ((Binding.name "pat_rews" , pat_rews ), [Simplifier.simp_add]),
+ ((Binding.name "dist_les" , dist_les ), [Simplifier.simp_add]),
+ ((Binding.name "dist_eqs" , dist_eqs ), [Simplifier.simp_add]),
+ ((Binding.name "inverts" , inverts ), [Simplifier.simp_add]),
+ ((Binding.name "injects" , injects ), [Simplifier.simp_add]),
+ ((Binding.name "copy_rews" , copy_rews ), [Simplifier.simp_add]),
+ ((Binding.name "match_rews", mat_rews ), [Simplifier.simp_add])]
|> Sign.parent_path
|> pair (iso_rews @ when_rews @ con_rews @ sel_rews @ dis_rews @
pat_rews @ dist_les @ dist_eqs @ copy_rews)
@@ -1003,14 +1010,14 @@
fun ind_rule (dname, rule) = ((Binding.empty, [rule]), [Induct.induct_type dname]);
in thy |> Sign.add_path comp_dnam
- |> (snd o (PureThy.add_thmss (map (Thm.no_attributes o apfst Binding.name) [
- ("take_rews" , take_rews ),
- ("take_lemmas", take_lemmas),
- ("finites" , finites ),
- ("finite_ind", [finite_ind]),
- ("ind" , [ind ]),
- ("coind" , [coind ])])))
- |> (snd o (PureThy.add_thmss (map ind_rule (dnames ~~ inducts))))
+ |> snd o PureThy.add_thmss [
+ ((Binding.name "take_rews" , take_rews ), [Simplifier.simp_add]),
+ ((Binding.name "take_lemmas", take_lemmas ), []),
+ ((Binding.name "finites" , finites ), []),
+ ((Binding.name "finite_ind" , [finite_ind]), []),
+ ((Binding.name "ind" , [ind] ), []),
+ ((Binding.name "coind" , [coind] ), [])]
+ |> snd o PureThy.add_thmss (map ind_rule (dnames ~~ inducts))
|> Sign.parent_path |> pair take_rews
end; (* let *)
end; (* local *)
--- a/src/HOLCF/Tools/fixrec_package.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Tools/fixrec_package.ML Mon May 11 17:20:52 2009 +0200
@@ -16,7 +16,7 @@
val setup: theory -> theory
end;
-structure FixrecPackage: FIXREC_PACKAGE =
+structure FixrecPackage :> FIXREC_PACKAGE =
struct
val fix_eq2 = @{thm fix_eq2};
@@ -36,6 +36,8 @@
infixr 6 ->>; val (op ->>) = cfunT;
+fun cfunsT (Ts, U) = foldr cfunT U Ts;
+
fun dest_cfunT (Type(@{type_name "->"}, [T, U])) = (T, U)
| dest_cfunT T = raise TYPE ("dest_cfunT", [T], []);
@@ -57,7 +59,9 @@
| tupleT [T] = T
| tupleT (T :: Ts) = HOLogic.mk_prodT (T, tupleT Ts);
-fun matchT T = body_cfun T ->> maybeT (tupleT (binder_cfun T));
+fun matchT (T, U) =
+ body_cfun T ->> cfunsT (binder_cfun T, U) ->> U;
+
(*************************************************************************)
(***************************** building terms ****************************)
@@ -240,10 +244,10 @@
fun result_type (Type(@{type_name "->"},[_,T])) (x::xs) = result_type T xs
| result_type T _ = T;
val v = Free(n, result_type T vs);
- val m = Const(match_name c, matchT T);
- val k = lambda_ctuple vs rhs;
+ val m = Const(match_name c, matchT (T, fastype_of rhs));
+ val k = big_lambdas vs rhs;
in
- (mk_bind (m`v, k), v, n::taken)
+ (m`v`k, v, n::taken)
end
| Free(n,_) => fixrec_err ("expected constructor, found free variable " ^ quote n)
| _ => fixrec_err "pre_build: invalid pattern";
--- a/src/HOLCF/Tools/pcpodef_package.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Tools/pcpodef_package.ML Mon May 11 17:20:52 2009 +0200
@@ -17,7 +17,7 @@
* (binding * binding) option -> theory -> Proof.state
end;
-structure PcpodefPackage: PCPODEF_PACKAGE =
+structure PcpodefPackage :> PCPODEF_PACKAGE =
struct
(** type definitions **)
@@ -66,9 +66,9 @@
NONE => (Binding.prefix_name "Rep_" name, Binding.prefix_name "Abs_" name)
| SOME morphs => morphs);
val RepC = Const (full Rep_name, newT --> oldT);
- fun lessC T = Const (@{const_name sq_le}, T --> T --> HOLogic.boolT);
- val less_def = Logic.mk_equals (lessC newT,
- Abs ("x", newT, Abs ("y", newT, lessC oldT $ (RepC $ Bound 1) $ (RepC $ Bound 0))));
+ fun belowC T = Const (@{const_name below}, T --> T --> HOLogic.boolT);
+ val below_def = Logic.mk_equals (belowC newT,
+ Abs ("x", newT, Abs ("y", newT, belowC oldT $ (RepC $ Bound 1) $ (RepC $ Bound 0))));
fun make_po tac thy1 =
let
@@ -76,22 +76,22 @@
|> TypedefPackage.add_typedef def (SOME name) (t, vs, mx) set opt_morphs tac;
val lthy3 = thy2
|> TheoryTarget.instantiation ([full_tname], lhs_tfrees, @{sort po});
- val less_def' = Syntax.check_term lthy3 less_def;
- val ((_, (_, less_definition')), lthy4) = lthy3
+ val below_def' = Syntax.check_term lthy3 below_def;
+ val ((_, (_, below_definition')), lthy4) = lthy3
|> Specification.definition (NONE,
- ((Binding.prefix_name "less_" (Binding.suffix_name "_def" name), []), less_def'));
+ ((Binding.prefix_name "below_" (Binding.suffix_name "_def" name), []), below_def'));
val ctxt_thy = ProofContext.init (ProofContext.theory_of lthy4);
- val less_definition = singleton (ProofContext.export lthy4 ctxt_thy) less_definition';
+ val below_definition = singleton (ProofContext.export lthy4 ctxt_thy) below_definition';
val thy5 = lthy4
|> Class.prove_instantiation_instance
- (K (Tactic.rtac (@{thm typedef_po} OF [type_definition, less_definition]) 1))
+ (K (Tactic.rtac (@{thm typedef_po} OF [type_definition, below_definition]) 1))
|> LocalTheory.exit_global;
- in ((type_definition, less_definition, set_def), thy5) end;
+ in ((type_definition, below_definition, set_def), thy5) end;
- fun make_cpo admissible (type_def, less_def, set_def) theory =
+ fun make_cpo admissible (type_def, below_def, set_def) theory =
let
val admissible' = fold_rule (the_list set_def) admissible;
- val cpo_thms = map (Thm.transfer theory) [type_def, less_def, admissible'];
+ val cpo_thms = map (Thm.transfer theory) [type_def, below_def, admissible'];
val theory' = theory
|> AxClass.prove_arity (full_tname, lhs_sorts, @{sort cpo})
(Tactic.rtac (@{thm typedef_cpo} OF cpo_thms) 1);
@@ -110,10 +110,10 @@
|> Sign.parent_path
end;
- fun make_pcpo UU_mem (type_def, less_def, set_def) theory =
+ fun make_pcpo UU_mem (type_def, below_def, set_def) theory =
let
val UU_mem' = fold_rule (the_list set_def) UU_mem;
- val pcpo_thms = map (Thm.transfer theory) [type_def, less_def, UU_mem'];
+ val pcpo_thms = map (Thm.transfer theory) [type_def, below_def, UU_mem'];
val theory' = theory
|> AxClass.prove_arity (full_tname, lhs_sorts, @{sort pcpo})
(Tactic.rtac (@{thm typedef_pcpo} OF pcpo_thms) 1);
--- a/src/HOLCF/Tr.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Tr.thy Mon May 11 17:20:52 2009 +0200
@@ -37,7 +37,7 @@
text {* distinctness for type @{typ tr} *}
-lemma dist_less_tr [simp]:
+lemma dist_below_tr [simp]:
"\<not> TT \<sqsubseteq> \<bottom>" "\<not> FF \<sqsubseteq> \<bottom>" "\<not> TT \<sqsubseteq> FF" "\<not> FF \<sqsubseteq> TT"
unfolding TT_def FF_def by simp_all
@@ -45,16 +45,16 @@
"TT \<noteq> \<bottom>" "FF \<noteq> \<bottom>" "TT \<noteq> FF" "\<bottom> \<noteq> TT" "\<bottom> \<noteq> FF" "FF \<noteq> TT"
unfolding TT_def FF_def by simp_all
-lemma TT_less_iff [simp]: "TT \<sqsubseteq> x \<longleftrightarrow> x = TT"
+lemma TT_below_iff [simp]: "TT \<sqsubseteq> x \<longleftrightarrow> x = TT"
by (induct x rule: tr_induct) simp_all
-lemma FF_less_iff [simp]: "FF \<sqsubseteq> x \<longleftrightarrow> x = FF"
+lemma FF_below_iff [simp]: "FF \<sqsubseteq> x \<longleftrightarrow> x = FF"
by (induct x rule: tr_induct) simp_all
-lemma not_less_TT_iff [simp]: "\<not> (x \<sqsubseteq> TT) \<longleftrightarrow> x = FF"
+lemma not_below_TT_iff [simp]: "\<not> (x \<sqsubseteq> TT) \<longleftrightarrow> x = FF"
by (induct x rule: tr_induct) simp_all
-lemma not_less_FF_iff [simp]: "\<not> (x \<sqsubseteq> FF) \<longleftrightarrow> x = TT"
+lemma not_below_FF_iff [simp]: "\<not> (x \<sqsubseteq> FF) \<longleftrightarrow> x = TT"
by (induct x rule: tr_induct) simp_all
--- a/src/HOLCF/Universal.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Universal.thy Mon May 11 17:20:52 2009 +0200
@@ -251,7 +251,7 @@
typedef (open) udom = "{S. udom.ideal S}"
by (fast intro: udom.ideal_principal)
-instantiation udom :: sq_ord
+instantiation udom :: below
begin
definition
@@ -262,16 +262,16 @@
instance udom :: po
by (rule udom.typedef_ideal_po
- [OF type_definition_udom sq_le_udom_def])
+ [OF type_definition_udom below_udom_def])
instance udom :: cpo
by (rule udom.typedef_ideal_cpo
- [OF type_definition_udom sq_le_udom_def])
+ [OF type_definition_udom below_udom_def])
lemma Rep_udom_lub:
"chain Y \<Longrightarrow> Rep_udom (\<Squnion>i. Y i) = (\<Union>i. Rep_udom (Y i))"
by (rule udom.typedef_ideal_rep_contlub
- [OF type_definition_udom sq_le_udom_def])
+ [OF type_definition_udom below_udom_def])
lemma ideal_Rep_udom: "udom.ideal (Rep_udom xs)"
by (rule Rep_udom [unfolded mem_Collect_eq])
@@ -291,7 +291,7 @@
apply (rule ideal_Rep_udom)
apply (erule Rep_udom_lub)
apply (rule Rep_udom_principal)
-apply (simp only: sq_le_udom_def)
+apply (simp only: below_udom_def)
done
text {* Universal domain is pointed *}
@@ -359,9 +359,9 @@
assume "y \<in> insert a A" and "(if x \<sqsubseteq> a then a else x) \<sqsubseteq> y"
thus "(if x \<sqsubseteq> a then a else x) = y"
apply auto
- apply (frule (1) trans_less)
+ apply (frule (1) below_trans)
apply (frule (1) x_eq)
- apply (rule antisym_less, assumption)
+ apply (rule below_antisym, assumption)
apply simp
apply (erule (1) x_eq)
done
@@ -503,7 +503,7 @@
done
lemma rank_leD: "rank x \<le> n \<Longrightarrow> cb_take n x = x"
-apply (rule antisym_less [OF cb_take_less])
+apply (rule below_antisym [OF cb_take_less])
apply (subst compact_approx_rank [symmetric])
apply (erule cb_take_chain_le)
done
@@ -727,7 +727,7 @@
apply (rule IH)
apply (simp add: less_max_iff_disj)
apply (erule place_sub_less)
- apply (erule rev_trans_less)
+ apply (erule rev_below_trans)
apply (rule sub_below)
done
qed
@@ -779,9 +779,9 @@
lemma basis_prj_mono: "ubasis_le a b \<Longrightarrow> basis_prj a \<sqsubseteq> basis_prj b"
proof (induct a b rule: ubasis_le.induct)
- case (ubasis_le_refl a) show ?case by (rule refl_less)
+ case (ubasis_le_refl a) show ?case by (rule below_refl)
next
- case (ubasis_le_trans a b c) thus ?case by - (rule trans_less)
+ case (ubasis_le_trans a b c) thus ?case by - (rule below_trans)
next
case (ubasis_le_lower S a i) thus ?case
apply (cases "node i a S \<in> range (basis_emb :: 'a compact_basis \<Rightarrow> nat)")
--- a/src/HOLCF/Up.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/Up.thy Mon May 11 17:20:52 2009 +0200
@@ -26,11 +26,11 @@
subsection {* Ordering on lifted cpo *}
-instantiation u :: (cpo) sq_ord
+instantiation u :: (cpo) below
begin
definition
- less_up_def:
+ below_up_def:
"(op \<sqsubseteq>) \<equiv> (\<lambda>x y. case x of Ibottom \<Rightarrow> True | Iup a \<Rightarrow>
(case y of Ibottom \<Rightarrow> False | Iup b \<Rightarrow> a \<sqsubseteq> b))"
@@ -38,13 +38,13 @@
end
lemma minimal_up [iff]: "Ibottom \<sqsubseteq> z"
-by (simp add: less_up_def)
+by (simp add: below_up_def)
-lemma not_Iup_less [iff]: "\<not> Iup x \<sqsubseteq> Ibottom"
-by (simp add: less_up_def)
+lemma not_Iup_below [iff]: "\<not> Iup x \<sqsubseteq> Ibottom"
+by (simp add: below_up_def)
-lemma Iup_less [iff]: "(Iup x \<sqsubseteq> Iup y) = (x \<sqsubseteq> y)"
-by (simp add: less_up_def)
+lemma Iup_below [iff]: "(Iup x \<sqsubseteq> Iup y) = (x \<sqsubseteq> y)"
+by (simp add: below_up_def)
subsection {* Lifted cpo is a partial order *}
@@ -52,17 +52,17 @@
proof
fix x :: "'a u"
show "x \<sqsubseteq> x"
- unfolding less_up_def by (simp split: u.split)
+ unfolding below_up_def by (simp split: u.split)
next
fix x y :: "'a u"
assume "x \<sqsubseteq> y" "y \<sqsubseteq> x" thus "x = y"
- unfolding less_up_def
- by (auto split: u.split_asm intro: antisym_less)
+ unfolding below_up_def
+ by (auto split: u.split_asm intro: below_antisym)
next
fix x y z :: "'a u"
assume "x \<sqsubseteq> y" "y \<sqsubseteq> z" thus "x \<sqsubseteq> z"
- unfolding less_up_def
- by (auto split: u.split_asm intro: trans_less)
+ unfolding below_up_def
+ by (auto split: u.split_asm intro: below_trans)
qed
lemma u_UNIV: "UNIV = insert Ibottom (range Iup)"
@@ -78,7 +78,7 @@
"range S <<| x \<Longrightarrow> range (\<lambda>i. Iup (S i)) <<| Iup x"
apply (rule is_lubI)
apply (rule ub_rangeI)
-apply (subst Iup_less)
+apply (subst Iup_below)
apply (erule is_ub_lub)
apply (case_tac u)
apply (drule ub_rangeD)
@@ -112,7 +112,7 @@
lemma up_lemma4:
"\<lbrakk>chain Y; Y j \<noteq> Ibottom\<rbrakk> \<Longrightarrow> chain (\<lambda>i. THE a. Iup a = Y (i + j))"
apply (rule chainI)
-apply (rule Iup_less [THEN iffD1])
+apply (rule Iup_below [THEN iffD1])
apply (subst up_lemma3, assumption+)+
apply (simp add: chainE)
done
@@ -235,9 +235,9 @@
by (simp add: up_def cont_Iup inst_up_pcpo)
lemma not_up_less_UU: "\<not> up\<cdot>x \<sqsubseteq> \<bottom>"
-by simp
+by simp (* FIXME: remove? *)
-lemma up_less [simp]: "(up\<cdot>x \<sqsubseteq> up\<cdot>y) = (x \<sqsubseteq> y)"
+lemma up_below [simp]: "up\<cdot>x \<sqsubseteq> up\<cdot>y \<longleftrightarrow> x \<sqsubseteq> y"
by (simp add: up_def cont_Iup)
lemma upE [cases type: u]: "\<lbrakk>p = \<bottom> \<Longrightarrow> Q; \<And>x. p = up\<cdot>x \<Longrightarrow> Q\<rbrakk> \<Longrightarrow> Q"
--- a/src/HOLCF/UpperPD.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/UpperPD.thy Mon May 11 17:20:52 2009 +0200
@@ -23,7 +23,7 @@
apply (drule (1) bspec, erule bexE)
apply (drule (1) bspec, erule bexE)
apply (erule rev_bexI)
-apply (erule (1) trans_less)
+apply (erule (1) below_trans)
done
interpretation upper_le: preorder upper_le
@@ -38,7 +38,7 @@
lemma PDPlus_upper_mono: "\<lbrakk>s \<le>\<sharp> t; u \<le>\<sharp> v\<rbrakk> \<Longrightarrow> PDPlus s u \<le>\<sharp> PDPlus t v"
unfolding upper_le_def Rep_PDPlus by fast
-lemma PDPlus_upper_less: "PDPlus t u \<le>\<sharp> t"
+lemma PDPlus_upper_le: "PDPlus t u \<le>\<sharp> t"
unfolding upper_le_def Rep_PDPlus by fast
lemma upper_le_PDUnit_PDUnit_iff [simp]:
@@ -97,7 +97,7 @@
"{S::'a pd_basis set. upper_le.ideal S}"
by (fast intro: upper_le.ideal_principal)
-instantiation upper_pd :: (profinite) sq_ord
+instantiation upper_pd :: (profinite) below
begin
definition
@@ -108,16 +108,16 @@
instance upper_pd :: (profinite) po
by (rule upper_le.typedef_ideal_po
- [OF type_definition_upper_pd sq_le_upper_pd_def])
+ [OF type_definition_upper_pd below_upper_pd_def])
instance upper_pd :: (profinite) cpo
by (rule upper_le.typedef_ideal_cpo
- [OF type_definition_upper_pd sq_le_upper_pd_def])
+ [OF type_definition_upper_pd below_upper_pd_def])
lemma Rep_upper_pd_lub:
"chain Y \<Longrightarrow> Rep_upper_pd (\<Squnion>i. Y i) = (\<Union>i. Rep_upper_pd (Y i))"
by (rule upper_le.typedef_ideal_rep_contlub
- [OF type_definition_upper_pd sq_le_upper_pd_def])
+ [OF type_definition_upper_pd below_upper_pd_def])
lemma ideal_Rep_upper_pd: "upper_le.ideal (Rep_upper_pd xs)"
by (rule Rep_upper_pd [unfolded mem_Collect_eq])
@@ -143,7 +143,7 @@
apply (rule ideal_Rep_upper_pd)
apply (erule Rep_upper_pd_lub)
apply (rule Rep_upper_principal)
-apply (simp only: sq_le_upper_pd_def)
+apply (simp only: below_upper_pd_def)
done
text {* Upper powerdomain is pointed *}
@@ -262,28 +262,28 @@
lemmas upper_plus_aci =
upper_plus_ac upper_plus_absorb upper_plus_left_absorb
-lemma upper_plus_less1: "xs +\<sharp> ys \<sqsubseteq> xs"
+lemma upper_plus_below1: "xs +\<sharp> ys \<sqsubseteq> xs"
apply (induct xs ys rule: upper_pd.principal_induct2, simp, simp)
-apply (simp add: PDPlus_upper_less)
+apply (simp add: PDPlus_upper_le)
done
-lemma upper_plus_less2: "xs +\<sharp> ys \<sqsubseteq> ys"
-by (subst upper_plus_commute, rule upper_plus_less1)
+lemma upper_plus_below2: "xs +\<sharp> ys \<sqsubseteq> ys"
+by (subst upper_plus_commute, rule upper_plus_below1)
lemma upper_plus_greatest: "\<lbrakk>xs \<sqsubseteq> ys; xs \<sqsubseteq> zs\<rbrakk> \<Longrightarrow> xs \<sqsubseteq> ys +\<sharp> zs"
apply (subst upper_plus_absorb [of xs, symmetric])
apply (erule (1) monofun_cfun [OF monofun_cfun_arg])
done
-lemma upper_less_plus_iff:
+lemma upper_below_plus_iff:
"xs \<sqsubseteq> ys +\<sharp> zs \<longleftrightarrow> xs \<sqsubseteq> ys \<and> xs \<sqsubseteq> zs"
apply safe
-apply (erule trans_less [OF _ upper_plus_less1])
-apply (erule trans_less [OF _ upper_plus_less2])
+apply (erule below_trans [OF _ upper_plus_below1])
+apply (erule below_trans [OF _ upper_plus_below2])
apply (erule (1) upper_plus_greatest)
done
-lemma upper_plus_less_unit_iff:
+lemma upper_plus_below_unit_iff:
"xs +\<sharp> ys \<sqsubseteq> {z}\<sharp> \<longleftrightarrow> xs \<sqsubseteq> {z}\<sharp> \<or> ys \<sqsubseteq> {z}\<sharp>"
apply (rule iffI)
apply (subgoal_tac
@@ -297,13 +297,13 @@
apply simp
apply simp
apply (erule disjE)
- apply (erule trans_less [OF upper_plus_less1])
- apply (erule trans_less [OF upper_plus_less2])
+ apply (erule below_trans [OF upper_plus_below1])
+ apply (erule below_trans [OF upper_plus_below2])
done
-lemma upper_unit_less_iff [simp]: "{x}\<sharp> \<sqsubseteq> {y}\<sharp> \<longleftrightarrow> x \<sqsubseteq> y"
+lemma upper_unit_below_iff [simp]: "{x}\<sharp> \<sqsubseteq> {y}\<sharp> \<longleftrightarrow> x \<sqsubseteq> y"
apply (rule iffI)
- apply (rule profinite_less_ext)
+ apply (rule profinite_below_ext)
apply (drule_tac f="approx i" in monofun_cfun_arg, simp)
apply (cut_tac x="approx i\<cdot>x" in compact_basis.compact_imp_principal, simp)
apply (cut_tac x="approx i\<cdot>y" in compact_basis.compact_imp_principal, simp)
@@ -311,10 +311,10 @@
apply (erule monofun_cfun_arg)
done
-lemmas upper_pd_less_simps =
- upper_unit_less_iff
- upper_less_plus_iff
- upper_plus_less_unit_iff
+lemmas upper_pd_below_simps =
+ upper_unit_below_iff
+ upper_below_plus_iff
+ upper_plus_below_unit_iff
lemma upper_unit_eq_iff [simp]: "{x}\<sharp> = {y}\<sharp> \<longleftrightarrow> x = y"
unfolding po_eq_conv by simp
@@ -323,10 +323,10 @@
unfolding inst_upper_pd_pcpo Rep_compact_bot [symmetric] by simp
lemma upper_plus_strict1 [simp]: "\<bottom> +\<sharp> ys = \<bottom>"
-by (rule UU_I, rule upper_plus_less1)
+by (rule UU_I, rule upper_plus_below1)
lemma upper_plus_strict2 [simp]: "xs +\<sharp> \<bottom> = \<bottom>"
-by (rule UU_I, rule upper_plus_less2)
+by (rule UU_I, rule upper_plus_below2)
lemma upper_unit_strict_iff [simp]: "{x}\<sharp> = \<bottom> \<longleftrightarrow> x = \<bottom>"
unfolding upper_unit_strict [symmetric] by (rule upper_unit_eq_iff)
@@ -407,11 +407,11 @@
lemma upper_bind_basis_mono:
"t \<le>\<sharp> u \<Longrightarrow> upper_bind_basis t \<sqsubseteq> upper_bind_basis u"
-unfolding expand_cfun_less
+unfolding expand_cfun_below
apply (erule upper_le_induct, safe)
apply (simp add: monofun_cfun)
-apply (simp add: trans_less [OF upper_plus_less1])
-apply (simp add: upper_less_plus_iff)
+apply (simp add: below_trans [OF upper_plus_below1])
+apply (simp add: upper_below_plus_iff)
done
definition
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOLCF/ex/Domain_ex.thy Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,221 @@
+(* Title: HOLCF/ex/Domain_ex.thy
+ Author: Brian Huffman
+*)
+
+header {* Domain package examples *}
+
+theory Domain_ex
+imports HOLCF
+begin
+
+text {* Domain constructors are strict by default. *}
+
+domain d1 = d1a | d1b "d1" "d1"
+
+lemma "d1b\<cdot>\<bottom>\<cdot>y = \<bottom>" by simp
+
+text {* Constructors can be made lazy using the @{text "lazy"} keyword. *}
+
+domain d2 = d2a | d2b (lazy "d2")
+
+lemma "d2b\<cdot>x \<noteq> \<bottom>" by simp
+
+text {* Strict and lazy arguments may be mixed arbitrarily. *}
+
+domain d3 = d3a | d3b (lazy "d2") "d2"
+
+lemma "P (d3b\<cdot>x\<cdot>y = \<bottom>) \<longleftrightarrow> P (y = \<bottom>)" by simp
+
+text {* Selectors can be used with strict or lazy constructor arguments. *}
+
+domain d4 = d4a | d4b (lazy d4b_left :: "d2") (d4b_right :: "d2")
+
+lemma "y \<noteq> \<bottom> \<Longrightarrow> d4b_left\<cdot>(d4b\<cdot>x\<cdot>y) = x" by simp
+
+text {* Mixfix declarations can be given for data constructors. *}
+
+domain d5 = d5a | d5b (lazy "d5") "d5" (infixl ":#:" 70)
+
+lemma "d5a \<noteq> x :#: y :#: z" by simp
+
+text {* Mixfix declarations can also be given for type constructors. *}
+
+domain ('a, 'b) lazypair (infixl ":*:" 25) =
+ lpair (lazy lfst :: 'a) (lazy lsnd :: 'b) (infixl ":*:" 75)
+
+lemma "\<forall>p::('a :*: 'b). p \<sqsubseteq> lfst\<cdot>p :*: lsnd\<cdot>p"
+by (rule allI, case_tac p, simp_all)
+
+text {* Non-recursive constructor arguments can have arbitrary types. *}
+
+domain ('a, 'b) d6 = d6 "int lift" "'a \<oplus> 'b u" (lazy "('a :*: 'b) \<times> ('b \<rightarrow> 'a)")
+
+text {*
+ Indirect recusion is allowed for sums, products, lifting, and the
+ continuous function space. However, the domain package currently
+ generates induction rules that are too weak. A fix is planned for
+ the next release.
+*}
+
+domain 'a d7 = d7a "'a d7 \<oplus> int lift" | d7b "'a \<otimes> 'a d7" | d7c "'a d7 \<rightarrow> 'a"
+
+thm d7.ind -- "note the lack of inductive hypotheses"
+
+text {*
+ Indirect recursion using previously-defined datatypes is currently
+ not allowed. This restriction should go away by the next release.
+*}
+(*
+domain 'a slist = SNil | SCons 'a "'a slist"
+domain 'a stree = STip | SBranch "'a stree slist" -- "illegal indirect recursion"
+*)
+
+text {* Mutually-recursive datatypes can be defined using the @{text "and"} keyword. *}
+
+domain d8 = d8a | d8b "d9" and d9 = d9a | d9b (lazy "d8")
+
+text {* Non-regular recursion is not allowed. *}
+(*
+domain ('a, 'b) altlist = ANil | ACons 'a "('b, 'a) altlist"
+ -- "illegal direct recursion with different arguments"
+domain 'a nest = Nest1 'a | Nest2 "'a nest nest"
+ -- "illegal direct recursion with different arguments"
+*)
+
+text {*
+ Mutually-recursive datatypes must have all the same type arguments,
+ not necessarily in the same order.
+*}
+
+domain ('a, 'b) list1 = Nil1 | Cons1 'a "('b, 'a) list2"
+ and ('b, 'a) list2 = Nil2 | Cons2 'b "('a, 'b) list1"
+
+text {* Induction rules for flat datatypes have no admissibility side-condition. *}
+
+domain 'a flattree = Tip | Branch "'a flattree" "'a flattree"
+
+lemma "\<lbrakk>P \<bottom>; P Tip; \<And>x y. \<lbrakk>x \<noteq> \<bottom>; y \<noteq> \<bottom>; P x; P y\<rbrakk> \<Longrightarrow> P (Branch\<cdot>x\<cdot>y)\<rbrakk> \<Longrightarrow> P x"
+by (rule flattree.ind) -- "no admissibility requirement"
+
+text {* Trivial datatypes will produce a warning message. *}
+
+domain triv = triv1 triv triv
+ -- "domain Domain_ex.triv is empty!"
+
+lemma "(x::triv) = \<bottom>" by (induct x, simp_all)
+
+
+subsection {* Generated constants and theorems *}
+
+domain 'a tree = Leaf (lazy 'a) | Node (left :: "'a tree") (lazy right :: "'a tree")
+
+lemmas tree_abs_defined_iff =
+ iso.abs_defined_iff [OF iso.intro [OF tree.abs_iso tree.rep_iso]]
+
+text {* Rules about ismorphism *}
+term tree_rep
+term tree_abs
+thm tree.rep_iso
+thm tree.abs_iso
+thm tree.iso_rews
+
+text {* Rules about constructors *}
+term Leaf
+term Node
+thm tree.Leaf_def tree.Node_def
+thm tree.exhaust
+thm tree.casedist
+thm tree.compacts
+thm tree.con_rews
+thm tree.dist_les
+thm tree.dist_eqs
+thm tree.inverts
+thm tree.injects
+
+text {* Rules about case combinator *}
+term tree_when
+thm tree.when_def
+thm tree.when_rews
+
+text {* Rules about selectors *}
+term left
+term right
+thm tree.sel_rews
+
+text {* Rules about discriminators *}
+term is_Leaf
+term is_Node
+thm tree.dis_rews
+
+text {* Rules about pattern match combinators *}
+term Leaf_pat
+term Node_pat
+thm tree.pat_rews
+
+text {* Rules about monadic pattern match combinators *}
+term match_Leaf
+term match_Node
+thm tree.match_rews
+
+text {* Rules about copy function *}
+term tree_copy
+thm tree.copy_def
+thm tree.copy_rews
+
+text {* Rules about take function *}
+term tree_take
+thm tree.take_def
+thm tree.take_rews
+thm tree.take_lemmas
+thm tree.finite_ind
+
+text {* Rules about finiteness predicate *}
+term tree_finite
+thm tree.finite_def
+thm tree.finites
+
+text {* Rules about bisimulation predicate *}
+term tree_bisim
+thm tree.bisim_def
+thm tree.coind
+
+text {* Induction rule *}
+thm tree.ind
+
+
+subsection {* Known bugs *}
+
+text {* Declaring a mixfix with spaces causes some strange parse errors. *}
+(*
+domain xx = xx ("x y")
+ -- "Inner syntax error: unexpected end of input"
+
+domain 'a foo = foo (sel::"'a") ("a b")
+ -- {* Inner syntax error at "= UU" *}
+*)
+
+text {*
+ I don't know what is going on here. The failed proof has to do with
+ the finiteness predicate.
+*}
+(*
+domain foo = Foo (lazy "bar") and bar = Bar
+ -- "Tactic failed."
+*)
+
+text {* Declaring class constraints on the LHS is currently broken. *}
+(*
+domain ('a::cpo) box = Box (lazy 'a)
+ -- "Malformed YXML encoding: multiple results"
+*)
+
+text {*
+ Class constraints on the RHS are not supported yet. This feature is
+ planned to replace the old-style LHS class constraints.
+*}
+(*
+domain 'a box = Box (lazy "'a::cpo")
+ -- {* Inconsistent sort constraint for type variable "'a" *}
+*)
+
+end
--- a/src/HOLCF/ex/Fixrec_ex.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/ex/Fixrec_ex.thy Mon May 11 17:20:52 2009 +0200
@@ -8,7 +8,7 @@
imports HOLCF
begin
-subsection {* basic fixrec examples *}
+subsection {* Basic @{text fixrec} examples *}
text {*
Fixrec patterns can mention any constructor defined by the domain
@@ -16,31 +16,31 @@
cpair, spair, sinl, sinr, up, ONE, TT, FF.
*}
-text {* typical usage is with lazy constructors *}
+text {* Typical usage is with lazy constructors. *}
fixrec down :: "'a u \<rightarrow> 'a"
where "down\<cdot>(up\<cdot>x) = x"
-text {* with strict constructors, rewrite rules may require side conditions *}
+text {* With strict constructors, rewrite rules may require side conditions. *}
fixrec from_sinl :: "'a \<oplus> 'b \<rightarrow> 'a"
where "x \<noteq> \<bottom> \<Longrightarrow> from_sinl\<cdot>(sinl\<cdot>x) = x"
-text {* lifting can turn a strict constructor into a lazy one *}
+text {* Lifting can turn a strict constructor into a lazy one. *}
fixrec from_sinl_up :: "'a u \<oplus> 'b \<rightarrow> 'a"
where "from_sinl_up\<cdot>(sinl\<cdot>(up\<cdot>x)) = x"
-subsection {* fixpat examples *}
+subsection {* Examples using @{text fixpat} *}
-text {* a type of lazy lists *}
+text {* A type of lazy lists. *}
domain 'a llist = lNil | lCons (lazy 'a) (lazy "'a llist")
-text {* zip function for lazy lists *}
+text {* A zip function for lazy lists. *}
-text {* notice that the patterns are not exhaustive *}
+text {* Notice that the patterns are not exhaustive. *}
fixrec
lzip :: "'a llist \<rightarrow> 'b llist \<rightarrow> ('a \<times> 'b) llist"
@@ -48,24 +48,59 @@
"lzip\<cdot>(lCons\<cdot>x\<cdot>xs)\<cdot>(lCons\<cdot>y\<cdot>ys) = lCons\<cdot><x,y>\<cdot>(lzip\<cdot>xs\<cdot>ys)"
| "lzip\<cdot>lNil\<cdot>lNil = lNil"
-text {* fixpat is useful for producing strictness theorems *}
-text {* note that pattern matching is done in left-to-right order *}
+text {* @{text fixpat} is useful for producing strictness theorems. *}
+text {* Note that pattern matching is done in left-to-right order. *}
fixpat lzip_stricts [simp]:
"lzip\<cdot>\<bottom>\<cdot>ys"
"lzip\<cdot>lNil\<cdot>\<bottom>"
"lzip\<cdot>(lCons\<cdot>x\<cdot>xs)\<cdot>\<bottom>"
-text {* fixpat can also produce rules for missing cases *}
+text {* @{text fixpat} can also produce rules for missing cases. *}
fixpat lzip_undefs [simp]:
"lzip\<cdot>lNil\<cdot>(lCons\<cdot>y\<cdot>ys)"
"lzip\<cdot>(lCons\<cdot>x\<cdot>xs)\<cdot>lNil"
-subsection {* skipping proofs of rewrite rules *}
+subsection {* Pattern matching with bottoms *}
+
+text {*
+ As an alternative to using @{text fixpat}, it is also possible to
+ use bottom as a constructor pattern. When using a bottom pattern,
+ the right-hand-side must also be bottom; otherwise, @{text fixrec}
+ will not be able to prove the equation.
+*}
+
+fixrec
+ from_sinr_up :: "'a \<oplus> 'b\<^sub>\<bottom> \<rightarrow> 'b"
+where
+ "from_sinr_up\<cdot>\<bottom> = \<bottom>"
+| "from_sinr_up\<cdot>(sinr\<cdot>(up\<cdot>x)) = x"
-text {* another zip function for lazy lists *}
+text {*
+ If the function is already strict in that argument, then the bottom
+ pattern does not change the meaning of the function. For example,
+ in the definition of @{term from_sinr_up}, the first equation is
+ actually redundant, and could have been proven separately by
+ @{text fixpat}.
+*}
+
+text {*
+ A bottom pattern can also be used to make a function strict in a
+ certain argument, similar to a bang-pattern in Haskell.
+*}
+
+fixrec
+ seq :: "'a \<rightarrow> 'b \<rightarrow> 'b"
+where
+ "seq\<cdot>\<bottom>\<cdot>y = \<bottom>"
+| "x \<noteq> \<bottom> \<Longrightarrow> seq\<cdot>x\<cdot>y = y"
+
+
+subsection {* Skipping proofs of rewrite rules *}
+
+text {* Another zip function for lazy lists. *}
text {*
Notice that this version has overlapping patterns.
@@ -85,7 +120,7 @@
does not produce any simp rules.
*}
-text {* simp rules can be generated later using fixpat *}
+text {* Simp rules can be generated later using @{text fixpat}. *}
fixpat lzip2_simps [simp]:
"lzip2\<cdot>(lCons\<cdot>x\<cdot>xs)\<cdot>(lCons\<cdot>y\<cdot>ys)"
@@ -97,16 +132,17 @@
"lzip2\<cdot>\<bottom>\<cdot>ys"
"lzip2\<cdot>(lCons\<cdot>x\<cdot>xs)\<cdot>\<bottom>"
-subsection {* mutual recursion with fixrec *}
-text {* tree and forest types *}
+subsection {* Mutual recursion with @{text fixrec} *}
+
+text {* Tree and forest types. *}
domain 'a tree = Leaf (lazy 'a) | Branch (lazy "'a forest")
and 'a forest = Empty | Trees (lazy "'a tree") "'a forest"
text {*
To define mutually recursive functions, separate the equations
- for each function using the keyword "and".
+ for each function using the keyword @{text "and"}.
*}
fixrec
@@ -125,10 +161,13 @@
text {*
Theorems generated:
- map_tree_def map_forest_def
- map_tree_unfold map_forest_unfold
- map_tree_simps map_forest_simps
- map_tree_map_forest_induct
+ @{text map_tree_def}
+ @{text map_forest_def}
+ @{text map_tree_unfold}
+ @{text map_forest_unfold}
+ @{text map_tree_simps}
+ @{text map_forest_simps}
+ @{text map_tree_map_forest_induct}
*}
end
--- a/src/HOLCF/ex/ROOT.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/ex/ROOT.ML Mon May 11 17:20:52 2009 +0200
@@ -4,4 +4,4 @@
*)
use_thys ["Dnat", "Stream", "Dagstuhl", "Focus_ex", "Fix2", "Hoare",
- "Loop", "Fixrec_ex", "Powerdomain_ex"];
+ "Loop", "Fixrec_ex", "Powerdomain_ex", "Domain_ex"];
--- a/src/HOLCF/ex/Stream.thy Mon May 11 09:39:53 2009 +0200
+++ b/src/HOLCF/ex/Stream.thy Mon May 11 17:20:52 2009 +0200
@@ -64,10 +64,10 @@
section "scons"
lemma scons_eq_UU: "(a && s = UU) = (a = UU)"
-by (auto, erule contrapos_pp, simp)
+by simp
lemma scons_not_empty: "[| a && x = UU; a ~= UU |] ==> R"
-by auto
+by simp
lemma stream_exhaust_eq: "(x ~= UU) = (EX a y. a ~= UU & x = a && y)"
by (auto,insert stream.exhaust [of x],auto)
@@ -382,7 +382,6 @@
lemma slen_scons_eq_rev: "(#x < Fin (Suc (Suc n))) = (!a y. x ~= a && y | a = \<bottom> | #y < Fin (Suc n))"
apply (rule stream.casedist [of x], auto)
- apply ((*drule sym,*) drule scons_eq_UU [THEN iffD1],auto)
apply (simp add: zero_inat_def)
apply (case_tac "#s") apply (simp_all add: iSuc_Fin)
apply (case_tac "#s") apply (simp_all add: iSuc_Fin)
@@ -874,7 +873,6 @@
lemma slen_sconc_finite1:
"[| #(x ooo y) = Infty; Fin n = #x |] ==> #y = Infty"
apply (case_tac "#y ~= Infty",auto)
-apply (simp only: slen_infinite [symmetric])
apply (drule_tac y=y in rt_sconc1)
apply (insert stream_finite_i_rt [of n "x ooo y"])
by (simp add: slen_infinite)
@@ -889,16 +887,15 @@
apply (drule ex_sconc,auto)
apply (erule contrapos_pp)
apply (insert stream_finite_i_rt)
- apply (simp add: slen_infinite,auto)
+ apply (fastsimp simp add: slen_infinite,auto)
by (simp add: sconc_def)
lemma sconc_finite: "(#x~=Infty & #y~=Infty) = (#(x ooo y)~=Infty)"
apply auto
- apply (case_tac "#x",auto)
- apply (erule contrapos_pp,simp)
- apply (erule slen_sconc_finite1,simp)
- apply (drule slen_sconc_infinite1 [of _ y],simp)
-by (drule slen_sconc_infinite2 [of _ x],simp)
+ apply (metis not_Infty_eq slen_sconc_finite1)
+ apply (metis not_Infty_eq slen_sconc_infinite1)
+apply (metis not_Infty_eq slen_sconc_infinite2)
+done
(* ----------------------------------------------------------------------- *)
--- a/src/Provers/Arith/cancel_div_mod.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Provers/Arith/cancel_div_mod.ML Mon May 11 17:20:52 2009 +0200
@@ -69,7 +69,7 @@
fun cancel ss t pq =
let val teqt' = Data.prove_eq_sums ss (t, rearrange t pq)
- in hd(Data.div_mod_eqs RL [teqt' RS transitive_thm]) end;
+ in hd (Data.div_mod_eqs RL [teqt' RS transitive_thm]) end;
fun proc ss t =
let val (divs,mods) = coll_div_mod t ([],[])
--- a/src/Pure/General/symbol.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Pure/General/symbol.ML Mon May 11 17:20:52 2009 +0200
@@ -18,6 +18,7 @@
val is_symbolic: symbol -> bool
val is_printable: symbol -> bool
val is_utf8_trailer: symbol -> bool
+ val name_of: symbol -> string
val eof: symbol
val is_eof: symbol -> bool
val not_eof: symbol -> bool
@@ -135,6 +136,10 @@
fun is_regular s =
not_eof s andalso s <> sync andalso s <> malformed andalso s <> end_malformed;
+fun name_of s = if is_symbolic s
+ then (unsuffix ">" o unprefix "\\<") s
+ else error (malformed_msg s);
+
(* ascii symbols *)
--- a/src/Pure/IsaMakefile Mon May 11 09:39:53 2009 +0200
+++ b/src/Pure/IsaMakefile Mon May 11 17:20:52 2009 +0200
@@ -40,9 +40,8 @@
Pure: $(OUT)/Pure
-$(OUT)/Pure: $(BOOTSTRAP_FILES) ../Tools/auto_solve.ML \
- ../Tools/quickcheck.ML Concurrent/ROOT.ML Concurrent/future.ML \
- Concurrent/mailbox.ML Concurrent/par_list.ML \
+$(OUT)/Pure: $(BOOTSTRAP_FILES) Concurrent/ROOT.ML \
+ Concurrent/future.ML Concurrent/mailbox.ML Concurrent/par_list.ML \
Concurrent/par_list_dummy.ML Concurrent/simple_thread.ML \
Concurrent/synchronized.ML Concurrent/task_queue.ML General/ROOT.ML \
General/alist.ML General/antiquote.ML General/balanced_tree.ML \
--- a/src/Pure/Isar/class_target.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Pure/Isar/class_target.ML Mon May 11 17:20:52 2009 +0200
@@ -278,7 +278,8 @@
val classrel = Goal.prove_global thy [] [] (Logic.mk_classrel (sub, sup))
(K tac);
val diff_sort = Sign.complete_sort thy [sup]
- |> subtract (op =) (Sign.complete_sort thy [sub]);
+ |> subtract (op =) (Sign.complete_sort thy [sub])
+ |> filter (is_class thy);
in
thy
|> AxClass.add_classrel classrel
--- a/src/Pure/Isar/code.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Pure/Isar/code.ML Mon May 11 17:20:52 2009 +0200
@@ -8,7 +8,7 @@
signature CODE =
sig
val add_eqn: thm -> theory -> theory
- val add_nonlinear_eqn: thm -> theory -> theory
+ val add_nbe_eqn: thm -> theory -> theory
val add_default_eqn: thm -> theory -> theory
val add_default_eqn_attribute: attribute
val add_default_eqn_attrib: Attrib.src
@@ -20,6 +20,8 @@
val add_inline: thm -> theory -> theory
val add_functrans: string * (theory -> (thm * bool) list -> (thm * bool) list option) -> theory -> theory
val del_functrans: string -> theory -> theory
+ val simple_functrans: (theory -> thm list -> thm list option)
+ -> theory -> (thm * bool) list -> (thm * bool) list option
val add_datatype: (string * typ) list -> theory -> theory
val add_datatype_cmd: string list -> theory -> theory
val type_interpretation:
@@ -29,8 +31,6 @@
val add_undefined: string -> theory -> theory
val purge_data: theory -> theory
- val coregular_algebra: theory -> Sorts.algebra
- val operational_algebra: theory -> (sort -> sort) * Sorts.algebra
val these_eqns: theory -> string -> (thm * bool) list
val these_raw_eqns: theory -> string -> (thm * bool) list
val get_datatype: theory -> string -> ((string * sort) list * (string * typ list) list)
@@ -111,7 +111,7 @@
(* code equations *)
type eqns = bool * (thm * bool) list lazy;
- (*default flag, theorems with linear flag (perhaps lazy)*)
+ (*default flag, theorems with proper flag (perhaps lazy)*)
fun pretty_lthms ctxt r = case Lazy.peek r
of SOME thms => map (ProofContext.pretty_thm ctxt o fst) (Exn.release thms)
@@ -124,18 +124,18 @@
val thy_ref = Theory.check_thy thy;
in Lazy.lazy (fn () => (f (Theory.deref thy_ref) o Lazy.force) r) end;
-fun add_drop_redundant thy (thm, linear) thms =
+fun add_drop_redundant thy (thm, proper) thms =
let
val args_of = snd o strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of;
val args = args_of thm;
val incr_idx = Logic.incr_indexes ([], Thm.maxidx_of thm + 1);
fun matches_args args' = length args <= length args' andalso
Pattern.matchess thy (args, (map incr_idx o curry Library.take (length args)) args');
- fun drop (thm', linear') = if (linear orelse not linear')
+ fun drop (thm', proper') = if (proper orelse not proper')
andalso matches_args (args_of thm') then
(warning ("Code generator: dropping redundant code equation\n" ^ Display.string_of_thm thm'); true)
else false;
- in (thm, linear) :: filter_out drop thms end;
+ in (thm, proper) :: filter_out drop thms end;
fun add_thm thy _ thm (false, thms) = (false, Lazy.map_force (add_drop_redundant thy thm) thms)
| add_thm thy true thm (true, thms) = (true, Lazy.map_force (fn thms => thms @ [thm]) thms)
@@ -458,49 +458,6 @@
cons (Thm.ctyp_of thy (TVar (x_i, sort)), Thm.ctyp_of thy ty)) env [];
in map (Thm.instantiate (instT, [])) thms' end;
-fun check_linear (eqn as (thm, linear)) =
- if linear then eqn else Code_Unit.bad_thm
- ("Duplicate variables on left hand side of code equation:\n"
- ^ Display.string_of_thm thm);
-
-fun mk_eqn thy linear =
- Code_Unit.error_thm ((if linear then check_linear else I) o Code_Unit.mk_eqn thy);
-fun mk_syntactic_eqn thy = Code_Unit.warning_thm (Code_Unit.mk_eqn thy);
-fun mk_default_eqn thy = Code_Unit.try_thm (check_linear o Code_Unit.mk_eqn thy);
-
-
-(** operational sort algebra and class discipline **)
-
-local
-
-fun arity_constraints thy algebra (class, tyco) =
- let
- val base_constraints = Sorts.mg_domain algebra tyco [class];
- val classparam_constraints = Sorts.complete_sort algebra [class]
- |> maps (map fst o these o try (#params o AxClass.get_info thy))
- |> map_filter (fn c => try (AxClass.param_of_inst thy) (c, tyco))
- |> maps (map fst o get_eqns thy)
- |> map (map (snd o dest_TVar) o Sign.const_typargs thy o Code_Unit.const_typ_eqn);
- val inter_sorts = map2 (curry (Sorts.inter_sort algebra));
- in fold inter_sorts classparam_constraints base_constraints end;
-
-fun retrieve_algebra thy operational =
- Sorts.subalgebra (Syntax.pp_global thy) operational
- (SOME o arity_constraints thy (Sign.classes_of thy))
- (Sign.classes_of thy);
-
-in
-
-fun coregular_algebra thy = retrieve_algebra thy (K true) |> snd;
-fun operational_algebra thy =
- let
- fun add_iff_operational class =
- can (AxClass.get_info thy) class ? cons class;
- val operational_classes = fold add_iff_operational (Sign.all_classes thy) []
- in retrieve_algebra thy (member (op =) operational_classes) end;
-
-end; (*local*)
-
(** interfaces and attributes **)
@@ -522,51 +479,47 @@
then SOME tyco else NONE
| _ => NONE;
-fun recheck_eqn thy = Code_Unit.error_thm
- (Code_Unit.assert_linear (is_some o get_datatype_of_constr thy) o apfst (Code_Unit.assert_eqn thy));
+fun is_constr thy = is_some o get_datatype_of_constr thy;
+
+fun assert_eqn thy = Code_Unit.assert_eqn thy (is_constr thy);
-fun recheck_eqns_const thy c eqns =
+fun assert_eqns_const thy c eqns =
let
- fun cert (eqn as (thm, _)) = if c = Code_Unit.const_eqn thm
+ fun cert (eqn as (thm, _)) = if c = Code_Unit.const_eqn thy thm
then eqn else error ("Wrong head of code equation,\nexpected constant "
^ Code_Unit.string_of_const thy c ^ "\n" ^ Display.string_of_thm thm)
- in map (cert o recheck_eqn thy) eqns end;
+ in map (cert o assert_eqn thy) eqns end;
fun change_eqns delete c f = (map_exec_purge (SOME [c]) o map_eqns
o (if delete then Symtab.map_entry c else Symtab.map_default (c, ((false, (true, Lazy.value [])), [])))
o apfst) (fn (_, eqns) => (true, f eqns));
-fun gen_add_eqn linear default thm thy =
- case (if default then mk_default_eqn thy else SOME o mk_eqn thy linear) thm
- of SOME (thm, _) =>
- let
- val c = Code_Unit.const_eqn thm;
- val _ = if not default andalso (is_some o AxClass.class_of_param thy) c
- then error ("Rejected polymorphic code equation for overloaded constant:\n"
- ^ Display.string_of_thm thm)
- else ();
- val _ = if not default andalso (is_some o get_datatype_of_constr thy) c
- then error ("Rejected code equation for datatype constructor:\n"
- ^ Display.string_of_thm thm)
- else ();
- in change_eqns false c (add_thm thy default (thm, linear)) thy end
+fun gen_add_eqn default (eqn as (thm, _)) thy =
+ let val c = Code_Unit.const_eqn thy thm
+ in change_eqns false c (add_thm thy default eqn) thy end;
+
+fun add_eqn thm thy =
+ gen_add_eqn false (Code_Unit.mk_eqn thy (is_constr thy) (thm, true)) thy;
+
+fun add_default_eqn thm thy =
+ case Code_Unit.mk_eqn_liberal thy (is_constr thy) thm
+ of SOME eqn => gen_add_eqn true eqn thy
| NONE => thy;
-val add_eqn = gen_add_eqn true false;
-val add_default_eqn = gen_add_eqn true true;
-val add_nonlinear_eqn = gen_add_eqn false false;
+fun add_nbe_eqn thm thy =
+ gen_add_eqn false (Code_Unit.mk_eqn thy (is_constr thy) (thm, false)) thy;
fun add_eqnl (c, lthms) thy =
let
- val lthms' = certificate thy (fn thy => recheck_eqns_const thy c) lthms;
+ val lthms' = certificate thy (fn thy => assert_eqns_const thy c) lthms;
in change_eqns false c (add_lthms lthms') thy end;
val add_default_eqn_attribute = Thm.declaration_attribute
(fn thm => Context.mapping (add_default_eqn thm) I);
val add_default_eqn_attrib = Attrib.internal (K add_default_eqn_attribute);
-fun del_eqn thm thy = case mk_syntactic_eqn thy thm
- of SOME (thm, _) => change_eqns true (Code_Unit.const_eqn thm) (del_thm thm) thy
+fun del_eqn thm thy = case Code_Unit.mk_eqn_liberal thy (is_constr thy) thm
+ of SOME (thm, _) => change_eqns true (Code_Unit.const_eqn thy thm) (del_thm thm) thy
| NONE => thy;
fun del_eqns c = change_eqns true c (K (false, Lazy.value []));
@@ -588,9 +541,9 @@
then insert (op =) c else I) cases []) cases;
in
thy
+ |> fold (del_eqns o fst) cs
|> map_exec_purge NONE
((map_dtyps o Symtab.map_default (tyco, [])) (cons (serial (), vs_cos))
- #> map_eqns (fold (Symtab.delete_safe o fst) cs)
#> (map_cases o apfst) drop_outdated_cases)
|> TypeInterpretation.data (tyco, serial ())
end;
@@ -606,7 +559,7 @@
fun add_case thm thy =
let
val (c, (k, case_pats)) = Code_Unit.case_cert thm;
- val _ = case filter (is_none o get_datatype_of_constr thy) case_pats
+ val _ = case filter_out (is_constr thy) case_pats
of [] => ()
| cs => error ("Non-constructor(s) in case certificate: " ^ commas (map quote cs));
val entry = (1 + Int.max (1, length case_pats), (k, case_pats))
@@ -631,6 +584,10 @@
(map_exec_purge NONE o map_thmproc o apsnd)
(delete_force "function transformer" name);
+fun simple_functrans f thy eqns = case f thy (map fst eqns)
+ of SOME thms' => SOME (map (rpair (forall snd eqns)) thms')
+ | NONE => NONE;
+
val _ = Context.>> (Context.map_theory
(let
fun mk_attribute f = Thm.declaration_attribute (fn thm => Context.mapping (f thm) I);
@@ -642,7 +599,7 @@
in
TypeInterpretation.init
#> add_del_attribute ("", (add_eqn, del_eqn))
- #> add_simple_attribute ("nbe", add_nonlinear_eqn)
+ #> add_simple_attribute ("nbe", add_nbe_eqn)
#> add_del_attribute ("inline", (add_inline, del_inline))
#> add_del_attribute ("post", (add_post, del_post))
end));
@@ -656,9 +613,7 @@
| apply_functrans thy c [] eqns = eqns
| apply_functrans thy c functrans eqns = eqns
|> perhaps (perhaps_loop (perhaps_apply functrans))
- |> (map o apfst) (AxClass.unoverload thy)
- |> recheck_eqns_const thy c
- |> (map o apfst) (AxClass.overload thy);
+ |> assert_eqns_const thy c;
fun rhs_conv conv thm = Thm.transitive thm ((conv o Thm.rhs_of) thm);
@@ -669,16 +624,17 @@
#> Logic.dest_equals
#> snd;
-fun preprocess thy functrans c eqns =
+fun preprocess thy c eqns =
let
val pre = (Simplifier.theory_context thy o #pre o the_thmproc o the_exec) thy;
+ val functrans = (map (fn (_, (_, f)) => f thy) o #functrans
+ o the_thmproc o the_exec) thy;
in
eqns
- |> (map o apfst) (AxClass.overload thy)
|> apply_functrans thy c functrans
|> (map o apfst) (Code_Unit.rewrite_eqn pre)
|> (map o apfst) (AxClass.unoverload thy)
- |> map (recheck_eqn thy)
+ |> map (assert_eqn thy)
|> burrow_fst (common_typ_eqns thy)
end;
@@ -712,14 +668,9 @@
|> burrow_fst (common_typ_eqns thy);
fun these_eqns thy c =
- let
- val functrans = (map (fn (_, (_, f)) => f thy) o #functrans
- o the_thmproc o the_exec) thy;
- in
- get_eqns thy c
- |> (map o apfst) (Thm.transfer thy)
- |> preprocess thy functrans c
- end;
+ get_eqns thy c
+ |> (map o apfst) (Thm.transfer thy)
+ |> preprocess thy c;
fun default_typscheme thy c =
let
@@ -728,10 +679,10 @@
fun strip_sorts (vs, ty) = (map (fn (v, _) => (v, [])) vs, ty);
in case AxClass.class_of_param thy c
of SOME class => ([(Name.aT, [class])], snd (the_const_typscheme c))
- | NONE => if is_some (get_datatype_of_constr thy c)
+ | NONE => if is_constr thy c
then strip_sorts (the_const_typscheme c)
else case get_eqns thy c
- of (thm, _) :: _ => snd (Code_Unit.head_eqn thy (Drule.zero_var_indexes thm))
+ of (thm, _) :: _ => (Code_Unit.typscheme_eqn thy o Drule.zero_var_indexes) thm
| [] => strip_sorts (the_const_typscheme c) end;
end; (*local*)
--- a/src/Pure/Isar/code_unit.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Pure/Isar/code_unit.ML Mon May 11 17:20:52 2009 +0200
@@ -6,12 +6,6 @@
signature CODE_UNIT =
sig
- (*generic non-sense*)
- val bad_thm: string -> 'a
- val error_thm: ('a -> 'b) -> 'a -> 'b
- val warning_thm: ('a -> 'b) -> 'a -> 'b option
- val try_thm: ('a -> 'b) -> 'a -> 'b option
-
(*typ instantiations*)
val typscheme: theory -> string * typ -> (string * sort) list * typ
val inst_thm: theory -> sort Vartab.table -> thm -> thm
@@ -35,17 +29,17 @@
-> string * ((string * sort) list * (string * typ list) list)
(*code equations*)
- val assert_eqn: theory -> thm -> thm
- val mk_eqn: theory -> thm -> thm * bool
- val assert_linear: (string -> bool) -> thm * bool -> thm * bool
- val const_eqn: thm -> string
- val const_typ_eqn: thm -> string * typ
- val head_eqn: theory -> thm -> string * ((string * sort) list * typ)
+ val mk_eqn: theory -> (string -> bool) -> thm * bool -> thm * bool
+ val mk_eqn_liberal: theory -> (string -> bool) -> thm -> (thm * bool) option
+ val assert_eqn: theory -> (string -> bool) -> thm * bool -> thm * bool
+ val const_eqn: theory -> thm -> string
+ val const_typ_eqn: thm -> string * typ
+ val typscheme_eqn: theory -> thm -> (string * sort) list * typ
val expand_eta: theory -> int -> thm -> thm
val rewrite_eqn: simpset -> thm -> thm
val rewrite_head: thm list -> thm -> thm
val norm_args: theory -> thm list -> thm list
- val norm_varnames: theory -> (string -> string) -> (string -> string) -> thm list -> thm list
+ val norm_varnames: theory -> thm list -> thm list
(*case certificates*)
val case_cert: thm -> string * (int * string list)
@@ -57,13 +51,6 @@
(* auxiliary *)
-exception BAD_THM of string;
-fun bad_thm msg = raise BAD_THM msg;
-fun error_thm f thm = f thm handle BAD_THM msg => error msg;
-fun warning_thm f thm = SOME (f thm) handle BAD_THM msg
- => (warning ("code generator: " ^ msg); NONE);
-fun try_thm f thm = SOME (f thm) handle BAD_THM _ => NONE;
-
fun string_of_typ thy = setmp show_sorts true (Syntax.string_of_typ_global thy);
fun string_of_const thy c = case AxClass.inst_of_param thy c
of SOME (c, tyco) => Sign.extern_const thy c ^ " " ^ enclose "[" "]" (Sign.extern_type thy tyco)
@@ -161,9 +148,10 @@
|> map (Conv.fconv_rule Drule.beta_eta_conversion)
end;
-fun canonical_tvars thy purify_tvar thm =
+fun canonical_tvars thy thm =
let
val ctyp = Thm.ctyp_of thy;
+ val purify_tvar = unprefix "'" #> Name.desymbolize false #> prefix "'";
fun tvars_subst_for thm = (fold_types o fold_atyps)
(fn TVar (v_i as (v, _), sort) => let
val v' = purify_tvar v
@@ -180,9 +168,10 @@
val (_, inst) = fold mk_inst (tvars_subst_for thm) (maxidx + 1, []);
in Thm.instantiate (inst, []) thm end;
-fun canonical_vars thy purify_var thm =
+fun canonical_vars thy thm =
let
val cterm = Thm.cterm_of thy;
+ val purify_var = Name.desymbolize false;
fun vars_subst_for thm = fold_aterms
(fn Var (v_i as (v, _), ty) => let
val v' = purify_var v
@@ -199,13 +188,14 @@
val (_, inst) = fold mk_inst (vars_subst_for thm) (maxidx + 1, []);
in Thm.instantiate ([], inst) thm end;
-fun canonical_absvars purify_var thm =
+fun canonical_absvars thm =
let
val t = Thm.plain_prop_of thm;
+ val purify_var = Name.desymbolize false;
val t' = Term.map_abs_vars purify_var t;
in Thm.rename_boundvars t t' thm end;
-fun norm_varnames thy purify_tvar purify_var thms =
+fun norm_varnames thy thms =
let
fun burrow_thms f [] = []
| burrow_thms f thms =
@@ -215,10 +205,10 @@
|> Conjunction.elim_balanced (length thms)
in
thms
- |> map (canonical_vars thy purify_var)
- |> map (canonical_absvars purify_var)
+ |> map (canonical_vars thy)
+ |> map canonical_absvars
|> map Drule.zero_var_indexes
- |> burrow_thms (canonical_tvars thy purify_tvar)
+ |> burrow_thms (canonical_tvars thy)
|> Drule.zero_var_indexes_list
end;
@@ -320,85 +310,96 @@
(* code equations *)
-fun assert_eqn thy thm =
+exception BAD_THM of string;
+fun bad_thm msg = raise BAD_THM msg;
+fun error_thm f thm = f thm handle BAD_THM msg => error msg;
+fun try_thm f thm = SOME (f thm) handle BAD_THM _ => NONE;
+
+fun is_linear thm =
+ let val (_, args) = (strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of) thm
+ in not (has_duplicates (op =) ((fold o fold_aterms)
+ (fn Var (v, _) => cons v | _ => I) args [])) end;
+
+fun gen_assert_eqn thy is_constr_head is_constr_pat (thm, proper) =
let
val (lhs, rhs) = (Logic.dest_equals o Thm.plain_prop_of) thm
handle TERM _ => bad_thm ("Not an equation: " ^ Display.string_of_thm thm)
- | THM _ => bad_thm ("Not an equation: " ^ Display.string_of_thm thm);
+ | THM _ => bad_thm ("Not an equation: " ^ Display.string_of_thm thm);
fun vars_of t = fold_aterms (fn Var (v, _) => insert (op =) v
- | Free _ => bad_thm ("Illegal free variable in rewrite theorem\n"
+ | Free _ => bad_thm ("Illegal free variable in equation\n"
^ Display.string_of_thm thm)
| _ => I) t [];
fun tvars_of t = fold_term_types (fn _ =>
fold_atyps (fn TVar (v, _) => insert (op =) v
| TFree _ => bad_thm
- ("Illegal free type variable in rewrite theorem\n" ^ Display.string_of_thm thm))) t [];
+ ("Illegal free type variable in equation\n" ^ Display.string_of_thm thm))) t [];
val lhs_vs = vars_of lhs;
val rhs_vs = vars_of rhs;
val lhs_tvs = tvars_of lhs;
val rhs_tvs = tvars_of rhs;
val _ = if null (subtract (op =) lhs_vs rhs_vs)
then ()
- else bad_thm ("Free variables on right hand side of rewrite theorem\n"
+ else bad_thm ("Free variables on right hand side of equation\n"
^ Display.string_of_thm thm);
val _ = if null (subtract (op =) lhs_tvs rhs_tvs)
then ()
- else bad_thm ("Free type variables on right hand side of rewrite theorem\n"
+ else bad_thm ("Free type variables on right hand side of equation\n"
^ Display.string_of_thm thm) val (head, args) = (strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of) thm;
- val (c, ty) = case head of Const c_ty => c_ty | _ =>
- bad_thm ("Equation not headed by constant\n" ^ Display.string_of_thm thm);
+ val (c, ty) = case head
+ of Const (c_ty as (_, ty)) => (AxClass.unoverload_const thy c_ty, ty)
+ | _ => bad_thm ("Equation not headed by constant\n" ^ Display.string_of_thm thm);
fun check _ (Abs _) = bad_thm
("Abstraction on left hand side of equation\n"
^ Display.string_of_thm thm)
| check 0 (Var _) = ()
| check _ (Var _) = bad_thm
- ("Variable with application on left hand side of code equation\n"
+ ("Variable with application on left hand side of equation\n"
^ Display.string_of_thm thm)
| check n (t1 $ t2) = (check (n+1) t1; check 0 t2)
- | check n (Const (_, ty)) = if n <> (length o fst o strip_type) ty
- then bad_thm
- ("Partially applied constant on left hand side of equation\n"
- ^ Display.string_of_thm thm)
- else ();
+ | check n (Const (c_ty as (c, ty))) = if n = (length o fst o strip_type) ty
+ then if not proper orelse is_constr_pat (AxClass.unoverload_const thy c_ty)
+ then ()
+ else bad_thm (quote c ^ " is not a constructor, on left hand side of equation\n"
+ ^ Display.string_of_thm thm)
+ else bad_thm
+ ("Partially applied constant " ^ quote c ^ " on left hand side of equation\n"
+ ^ Display.string_of_thm thm);
val _ = map (check 0) args;
+ val _ = if not proper orelse is_linear thm then ()
+ else bad_thm ("Duplicate variables on left hand side of equation\n"
+ ^ Display.string_of_thm thm);
+ val _ = if (is_none o AxClass.class_of_param thy) c
+ then ()
+ else bad_thm ("Polymorphic constant as head in equation\n"
+ ^ Display.string_of_thm thm)
+ val _ = if not (is_constr_head c)
+ then ()
+ else bad_thm ("Constructor as head in equation\n"
+ ^ Display.string_of_thm thm)
val ty_decl = Sign.the_const_type thy c;
val _ = if Sign.typ_equiv thy (Type.strip_sorts ty_decl, Type.strip_sorts ty)
then () else bad_thm ("Type\n" ^ string_of_typ thy ty
- ^ "\nof code equation\n"
+ ^ "\nof equation\n"
^ Display.string_of_thm thm
^ "\nis incompatible with declared function type\n"
^ string_of_typ thy ty_decl)
- in thm end;
-
-fun add_linear thm =
- let
- val (_, args) = (strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of) thm;
- val linear = not (has_duplicates (op =)
- ((fold o fold_aterms) (fn Var (v, _) => cons v | _ => I) args []))
- in (thm, linear) end;
+ in (thm, proper) end;
-fun assert_pat is_cons thm =
- let
- val args = (snd o strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of) thm;
- val _ = (map o map_aterms) (fn t as Const (c, _) => if is_cons c then t
- else bad_thm ("Not a constructor on left hand side of equation: "
- ^ quote c ^ ",\n in equation\n" ^ Display.string_of_thm thm)
- | t => t) args;
- in thm end;
-
-fun assert_linear is_cons (thm, false) = (thm, false)
- | assert_linear is_cons (thm, true) = if snd (add_linear (assert_pat is_cons thm)) then (thm, true)
- else bad_thm
- ("Duplicate variables on left hand side of code equation:\n"
- ^ Display.string_of_thm thm);
-
-
-fun mk_eqn thy = add_linear o assert_eqn thy o AxClass.unoverload thy
- o LocalDefs.meta_rewrite_rule (ProofContext.init thy);
+fun assert_eqn thy is_constr = error_thm (gen_assert_eqn thy is_constr is_constr);
val const_typ_eqn = dest_Const o fst o strip_comb o fst o Logic.dest_equals o Thm.plain_prop_of;
-val const_eqn = fst o const_typ_eqn;
-fun head_eqn thy thm = let val (c, ty) = const_typ_eqn thm in (c, typscheme thy (c, ty)) end;
+
+fun typscheme_eqn thy = typscheme thy o const_typ_eqn;
+
+(*these are permissive wrt. to overloaded constants!*)
+fun mk_eqn thy is_constr_head = error_thm (gen_assert_eqn thy is_constr_head (K true)) o
+ apfst (LocalDefs.meta_rewrite_rule (ProofContext.init thy));
+
+fun mk_eqn_liberal thy is_constr_head = Option.map (fn (thm, _) => (thm, is_linear thm))
+ o try_thm (gen_assert_eqn thy is_constr_head (K true))
+ o rpair false o LocalDefs.meta_rewrite_rule (ProofContext.init thy);
+
+fun const_eqn thy = AxClass.unoverload_const thy o const_typ_eqn;
(* case cerificates *)
--- a/src/Pure/ProofGeneral/ROOT.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Pure/ProofGeneral/ROOT.ML Mon May 11 17:20:52 2009 +0200
@@ -14,11 +14,7 @@
use "pgip_isabelle.ML";
-(use
- |> setmp Proofterm.proofs 1
- |> setmp quick_and_dirty true
- |> setmp auto_quickcheck true
- |> setmp auto_solve true) "preferences.ML";
+use "preferences.ML";
use "pgip_parser.ML";
--- a/src/Pure/ProofGeneral/preferences.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Pure/ProofGeneral/preferences.ML Mon May 11 17:20:52 2009 +0200
@@ -6,6 +6,10 @@
signature PREFERENCES =
sig
+ val category_display: string
+ val category_advanced_display: string
+ val category_tracing: string
+ val category_proof: string
type preference =
{name: string,
descr: string,
@@ -29,6 +33,14 @@
structure Preferences: PREFERENCES =
struct
+(* categories *)
+
+val category_display = "Display";
+val category_advanced_display = "Advanced Display";
+val category_tracing = "Tracing";
+val category_proof = "Proof"
+
+
(* preferences and preference tables *)
type preference =
@@ -66,11 +78,11 @@
(* preferences of Pure *)
-val proof_pref =
+val proof_pref = setmp Proofterm.proofs 1 (fn () =>
let
fun get () = PgipTypes.bool_to_pgstring (! Proofterm.proofs >= 2);
fun set s = Proofterm.proofs := (if PgipTypes.read_pgipbool s then 2 else 1);
- in mkpref get set PgipTypes.Pgipbool "full-proofs" "Record full proof objects internally" end;
+ in mkpref get set PgipTypes.Pgipbool "full-proofs" "Record full proof objects internally" end) ();
val thm_depsN = "thm_deps";
val thm_deps_pref =
@@ -145,24 +157,13 @@
bool_pref Toplevel.debug
"debugging"
"Whether to enable debugging.",
- bool_pref Quickcheck.auto
- "auto-quickcheck"
- "Whether to enable quickcheck automatically.",
- nat_pref Quickcheck.auto_time_limit
- "auto-quickcheck-time-limit"
- "Time limit for automatic quickcheck (in milliseconds).",
- bool_pref AutoSolve.auto
- "auto-solve"
- "Try to solve newly declared lemmas with existing theorems.",
- nat_pref AutoSolve.auto_time_limit
- "auto-solve-time-limit"
- "Time limit for seeking automatic solutions (in milliseconds).",
thm_deps_pref];
val proof_preferences =
- [bool_pref quick_and_dirty
- "quick-and-dirty"
- "Take a few short cuts",
+ [setmp quick_and_dirty true (fn () =>
+ bool_pref quick_and_dirty
+ "quick-and-dirty"
+ "Take a few short cuts") (),
bool_pref Toplevel.skip_proofs
"skip-proofs"
"Skip over proofs (interactive-only)",
@@ -175,10 +176,10 @@
"Check proofs in parallel"];
val pure_preferences =
- [("Display", display_preferences),
- ("Advanced Display", advanced_display_preferences),
- ("Tracing", tracing_preferences),
- ("Proof", proof_preferences)];
+ [(category_display, display_preferences),
+ (category_advanced_display, advanced_display_preferences),
+ (category_tracing, tracing_preferences),
+ (category_proof, proof_preferences)];
(* table of categories and preferences; names must be unique *)
@@ -203,6 +204,6 @@
else
if exists (fn {name, ...} => name = #name pref) prefs
then (warning ("Preference already exists: " ^ quote (#name pref)); (cat, prefs))
- else (cat, pref :: prefs));
+ else (cat, prefs @ [pref]));
end;
--- a/src/Pure/Tools/ROOT.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Pure/Tools/ROOT.ML Mon May 11 17:20:52 2009 +0200
@@ -1,16 +1,9 @@
-(* Title: Pure/Tools/ROOT.ML
-
-Miscellaneous tools and packages for Pure Isabelle.
-*)
+(* Miscellaneous tools and packages for Pure Isabelle *)
use "named_thms.ML";
-(*basic XML support*)
use "xml_syntax.ML";
use "find_theorems.ML";
use "find_consts.ML";
-(*quickcheck/autosolve needed here because of pg preferences*)
-use "../../Tools/quickcheck.ML";
-use "../../Tools/auto_solve.ML";
--- a/src/Pure/Tools/find_theorems.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Pure/Tools/find_theorems.ML Mon May 11 17:20:52 2009 +0200
@@ -7,7 +7,7 @@
signature FIND_THEOREMS =
sig
datatype 'term criterion =
- Name of string | Intro | Elim | Dest | Solves | Simp of 'term |
+ Name of string | Intro | IntroIff | Elim | Dest | Solves | Simp of 'term |
Pattern of 'term
val tac_limit: int ref
val limit: int ref
@@ -24,11 +24,12 @@
(** search criteria **)
datatype 'term criterion =
- Name of string | Intro | Elim | Dest | Solves | Simp of 'term |
+ Name of string | Intro | IntroIff | Elim | Dest | Solves | Simp of 'term |
Pattern of 'term;
fun read_criterion _ (Name name) = Name name
| read_criterion _ Intro = Intro
+ | read_criterion _ IntroIff = IntroIff
| read_criterion _ Elim = Elim
| read_criterion _ Dest = Dest
| read_criterion _ Solves = Solves
@@ -42,6 +43,7 @@
(case c of
Name name => Pretty.str (prfx "name: " ^ quote name)
| Intro => Pretty.str (prfx "intro")
+ | IntroIff => Pretty.str (prfx "introiff")
| Elim => Pretty.str (prfx "elim")
| Dest => Pretty.str (prfx "dest")
| Solves => Pretty.str (prfx "solves")
@@ -74,17 +76,40 @@
fun is_nontrivial thy = Term.is_Const o Term.head_of o ObjectLogic.drop_judgment thy;
+(* Note: ("op =" : "bool --> bool --> bool") does not exist in Pure. *)
+fun is_Iff c =
+ (case dest_Const c of
+ ("op =", ty) =>
+ (ty
+ |> strip_type
+ |> swap
+ |> (op ::)
+ |> map (fst o dest_Type)
+ |> forall (curry (op =) "bool")
+ handle TYPE _ => false)
+ | _ => false);
+
(*extract terms from term_src, refine them to the parts that concern us,
if po try match them against obj else vice versa.
trivial matches are ignored.
returns: smallest substitution size*)
-fun is_matching_thm (extract_terms, refine_term) ctxt po obj term_src =
+fun is_matching_thm doiff (extract_terms, refine_term) ctxt po obj term_src =
let
val thy = ProofContext.theory_of ctxt;
+ val chkmatch = obj |> (if po then rpair else pair) #> Pattern.matches thy;
fun matches pat =
- is_nontrivial thy pat andalso
- Pattern.matches thy (if po then (pat, obj) else (obj, pat));
+ let
+ val jpat = ObjectLogic.drop_judgment thy pat;
+ val c = Term.head_of jpat;
+ val pats =
+ if Term.is_Const c
+ then if doiff andalso is_Iff c
+ then pat :: map (ObjectLogic.ensure_propT thy) ((snd o strip_comb) jpat)
+ |> filter (is_nontrivial thy)
+ else [pat]
+ else [];
+ in filter chkmatch pats end;
fun substsize pat =
let val (_, subst) =
@@ -96,7 +121,9 @@
val match_thm = matches o refine_term;
in
- map (substsize o refine_term) (filter match_thm (extract_terms term_src))
+ map match_thm (extract_terms term_src)
+ |> flat
+ |> map substsize
|> bestmatch
end;
@@ -117,7 +144,7 @@
hd o Logic.strip_imp_prems);
val prems = Logic.prems_of_goal goal 1;
- fun try_subst prem = is_matching_thm extract_dest ctxt true prem thm;
+ fun try_subst prem = is_matching_thm false extract_dest ctxt true prem thm;
val successful = prems |> map_filter try_subst;
in
(*if possible, keep best substitution (one with smallest size)*)
@@ -127,11 +154,11 @@
then SOME (Thm.nprems_of thm - 1, foldr1 Int.min successful) else NONE
end;
-fun filter_intro ctxt goal (_, thm) =
+fun filter_intro doiff ctxt goal (_, thm) =
let
val extract_intro = (single o Thm.full_prop_of, Logic.strip_imp_concl);
val concl = Logic.concl_of_goal goal 1;
- val ss = is_matching_thm extract_intro ctxt true concl thm;
+ val ss = is_matching_thm doiff extract_intro ctxt true concl thm;
in
if is_some ss then SOME (Thm.nprems_of thm, the ss) else NONE
end;
@@ -148,7 +175,7 @@
val rule_tree = combine rule_mp rule_concl;
fun goal_tree prem = combine prem goal_concl;
fun try_subst prem =
- is_matching_thm (single, I) ctxt true (goal_tree prem) rule_tree;
+ is_matching_thm false (single, I) ctxt true (goal_tree prem) rule_tree;
val successful = prems |> map_filter try_subst;
in
(*elim rules always have assumptions, so an elim with one
@@ -183,7 +210,7 @@
val mksimps = Simplifier.mksimps (Simplifier.local_simpset_of ctxt);
val extract_simp =
(map Thm.full_prop_of o mksimps, #1 o Logic.dest_equals o Logic.strip_imp_concl);
- val ss = is_matching_thm extract_simp ctxt false t thm;
+ val ss = is_matching_thm false extract_simp ctxt false t thm;
in
if is_some ss then SOME (Thm.nprems_of thm, the ss) else NONE
end;
@@ -233,7 +260,8 @@
| filter_crit _ NONE Elim = err_no_goal "elim"
| filter_crit _ NONE Dest = err_no_goal "dest"
| filter_crit _ NONE Solves = err_no_goal "solves"
- | filter_crit ctxt (SOME goal) Intro = apfst (filter_intro ctxt (fix_goal goal))
+ | filter_crit ctxt (SOME goal) Intro = apfst (filter_intro false ctxt (fix_goal goal))
+ | filter_crit ctxt (SOME goal) IntroIff = apfst (filter_intro true ctxt (fix_goal goal))
| filter_crit ctxt (SOME goal) Elim = apfst (filter_elim ctxt (fix_goal goal))
| filter_crit ctxt (SOME goal) Dest = apfst (filter_dest ctxt (fix_goal goal))
| filter_crit ctxt (SOME goal) Solves = apfst (filter_solves ctxt goal)
@@ -428,6 +456,7 @@
val criterion =
P.reserved "name" |-- P.!!! (P.$$$ ":" |-- P.xname) >> Name ||
P.reserved "intro" >> K Intro ||
+ P.reserved "introiff" >> K IntroIff ||
P.reserved "elim" >> K Elim ||
P.reserved "dest" >> K Dest ||
P.reserved "solves" >> K Solves ||
--- a/src/Pure/axclass.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Pure/axclass.ML Mon May 11 17:20:52 2009 +0200
@@ -286,74 +286,6 @@
handle TYPE (msg, _, _) => error msg;
-(* primitive rules *)
-
-fun add_classrel th thy =
- let
- fun err () = raise THM ("add_classrel: malformed class relation", 0, [th]);
- val prop = Thm.plain_prop_of (Thm.transfer thy th);
- val rel = Logic.dest_classrel prop handle TERM _ => err ();
- val (c1, c2) = cert_classrel thy rel handle TYPE _ => err ();
- in
- thy
- |> Sign.primitive_classrel (c1, c2)
- |> put_classrel ((c1, c2), Thm.close_derivation (Drule.unconstrainTs th))
- |> perhaps complete_arities
- end;
-
-fun add_arity th thy =
- let
- fun err () = raise THM ("add_arity: malformed type arity", 0, [th]);
- val prop = Thm.plain_prop_of (Thm.transfer thy th);
- val (t, Ss, c) = Logic.dest_arity prop handle TERM _ => err ();
- val _ = map (Sign.certify_sort thy) Ss = Ss orelse err ();
- val _ = case filter_out (fn c => can (get_inst_param thy) (c, t)) (params_of thy c)
- of [] => ()
- | cs => Output.legacy_feature
- ("Missing specifications for overloaded parameters " ^ commas_quote cs)
- val th' = Drule.unconstrainTs th;
- in
- thy
- |> Sign.primitive_arity (t, Ss, [c])
- |> put_arity ((t, Ss, c), th')
- end;
-
-
-(* tactical proofs *)
-
-fun prove_classrel raw_rel tac thy =
- let
- val ctxt = ProofContext.init thy;
- val (c1, c2) = cert_classrel thy raw_rel;
- val th = Goal.prove ctxt [] [] (Logic.mk_classrel (c1, c2)) (K tac) handle ERROR msg =>
- cat_error msg ("The error(s) above occurred while trying to prove class relation " ^
- quote (Syntax.string_of_classrel ctxt [c1, c2]));
- in
- thy
- |> PureThy.add_thms [((Binding.name
- (prefix classrel_prefix (Logic.name_classrel (c1, c2))), th), [])]
- |-> (fn [th'] => add_classrel th')
- end;
-
-fun prove_arity raw_arity tac thy =
- let
- val ctxt = ProofContext.init thy;
- val arity = Sign.cert_arity thy raw_arity;
- val names = map (prefix arity_prefix) (Logic.name_arities arity);
- val props = Logic.mk_arities arity;
- val ths = Goal.prove_multi ctxt [] [] props
- (fn _ => Goal.precise_conjunction_tac (length props) 1 THEN tac) handle ERROR msg =>
- cat_error msg ("The error(s) above occurred while trying to prove type arity " ^
- quote (Syntax.string_of_arity ctxt arity));
- in
- thy
- |> PureThy.add_thms (map (rpair []) (map Binding.name names ~~ ths))
- |-> fold add_arity
- end;
-
-
-(* instance parameters and overloaded definitions *)
-
(* declaration and definition of instances of overloaded constants *)
fun declare_overloaded (c, T) thy =
@@ -398,6 +330,74 @@
end;
+(* primitive rules *)
+
+fun add_classrel th thy =
+ let
+ fun err () = raise THM ("add_classrel: malformed class relation", 0, [th]);
+ val prop = Thm.plain_prop_of (Thm.transfer thy th);
+ val rel = Logic.dest_classrel prop handle TERM _ => err ();
+ val (c1, c2) = cert_classrel thy rel handle TYPE _ => err ();
+ in
+ thy
+ |> Sign.primitive_classrel (c1, c2)
+ |> put_classrel ((c1, c2), Thm.close_derivation (Drule.unconstrainTs th))
+ |> perhaps complete_arities
+ end;
+
+fun add_arity th thy =
+ let
+ fun err () = raise THM ("add_arity: malformed type arity", 0, [th]);
+ val prop = Thm.plain_prop_of (Thm.transfer thy th);
+ val (t, Ss, c) = Logic.dest_arity prop handle TERM _ => err ();
+ val T = Type (t, map TFree (Name.names Name.context Name.aT Ss));
+ val missing_params = Sign.complete_sort thy [c]
+ |> maps (these o Option.map #params o try (get_info thy))
+ |> filter_out (fn (const, _) => can (get_inst_param thy) (const, t))
+ |> (map o apsnd o map_atyps) (K T);
+ val _ = map (Sign.certify_sort thy) Ss = Ss orelse err ();
+ val th' = Drule.unconstrainTs th;
+ in
+ thy
+ |> fold (snd oo declare_overloaded) missing_params
+ |> Sign.primitive_arity (t, Ss, [c])
+ |> put_arity ((t, Ss, c), th')
+ end;
+
+
+(* tactical proofs *)
+
+fun prove_classrel raw_rel tac thy =
+ let
+ val ctxt = ProofContext.init thy;
+ val (c1, c2) = cert_classrel thy raw_rel;
+ val th = Goal.prove ctxt [] [] (Logic.mk_classrel (c1, c2)) (K tac) handle ERROR msg =>
+ cat_error msg ("The error(s) above occurred while trying to prove class relation " ^
+ quote (Syntax.string_of_classrel ctxt [c1, c2]));
+ in
+ thy
+ |> PureThy.add_thms [((Binding.name
+ (prefix classrel_prefix (Logic.name_classrel (c1, c2))), th), [])]
+ |-> (fn [th'] => add_classrel th')
+ end;
+
+fun prove_arity raw_arity tac thy =
+ let
+ val ctxt = ProofContext.init thy;
+ val arity = Sign.cert_arity thy raw_arity;
+ val names = map (prefix arity_prefix) (Logic.name_arities arity);
+ val props = Logic.mk_arities arity;
+ val ths = Goal.prove_multi ctxt [] [] props
+ (fn _ => Goal.precise_conjunction_tac (length props) 1 THEN tac) handle ERROR msg =>
+ cat_error msg ("The error(s) above occurred while trying to prove type arity " ^
+ quote (Syntax.string_of_arity ctxt arity));
+ in
+ thy
+ |> PureThy.add_thms (map (rpair []) (map Binding.name names ~~ ths))
+ |-> fold add_arity
+ end;
+
+
(** class definitions **)
--- a/src/Pure/name.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Pure/name.ML Mon May 11 17:20:52 2009 +0200
@@ -28,6 +28,7 @@
val variants: string list -> context -> string list * context
val variant_list: string list -> string list -> string list
val variant: string list -> string -> string
+ val desymbolize: bool -> string -> string
end;
structure Name: NAME =
@@ -144,4 +145,31 @@
fun variant_list used names = #1 (make_context used |> variants names);
fun variant used = singleton (variant_list used);
+
+(* names conforming to typical requirements of identifiers in the world outside *)
+
+fun desymbolize upper "" = if upper then "X" else "x"
+ | desymbolize upper s =
+ let
+ val xs as (x :: _) = Symbol.explode s;
+ val ys = if Symbol.is_ascii_letter x orelse Symbol.is_symbolic x then xs
+ else "x" :: xs;
+ fun is_valid x =
+ Symbol.is_ascii_letter x orelse Symbol.is_ascii_digit x orelse x = "'";
+ fun sep [] = []
+ | sep (xs as "_" :: _) = xs
+ | sep xs = "_" :: xs;
+ fun desep ("_" :: xs) = xs
+ | desep xs = xs;
+ fun desymb x xs = if is_valid x
+ then x :: xs
+ else if Symbol.is_symbolic x
+ then "_" :: explode (Symbol.name_of x) @ sep xs
+ else
+ sep xs
+ fun upper_lower cs = if upper then nth_map 0 Symbol.to_ascii_upper cs
+ else (if forall Symbol.is_ascii_upper cs
+ then map else nth_map 0) Symbol.to_ascii_lower cs;
+ in fold_rev desymb ys [] |> desep |> upper_lower |> implode end;
+
end;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Tools/Code_Generator.thy Mon May 11 17:20:52 2009 +0200
@@ -0,0 +1,27 @@
+(* Title: Tools/Code_Generator.thy
+ Author: Florian Haftmann, TU Muenchen
+*)
+
+header {* Loading the code generator modules *}
+
+theory Code_Generator
+imports Pure
+uses
+ "~~/src/Tools/value.ML"
+ "~~/src/Tools/quickcheck.ML"
+ "~~/src/Tools/code/code_wellsorted.ML"
+ "~~/src/Tools/code/code_thingol.ML"
+ "~~/src/Tools/code/code_printer.ML"
+ "~~/src/Tools/code/code_target.ML"
+ "~~/src/Tools/code/code_ml.ML"
+ "~~/src/Tools/code/code_haskell.ML"
+ "~~/src/Tools/nbe.ML"
+begin
+
+setup {*
+ Code_ML.setup
+ #> Code_Haskell.setup
+ #> Nbe.setup
+*}
+
+end
\ No newline at end of file
--- a/src/Tools/auto_solve.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Tools/auto_solve.ML Mon May 11 17:20:52 2009 +0200
@@ -14,18 +14,34 @@
val auto : bool ref
val auto_time_limit : int ref
val limit : int ref
-
- val seek_solution : bool -> Proof.state -> Proof.state
end;
structure AutoSolve : AUTO_SOLVE =
struct
+(* preferences *)
+
val auto = ref false;
val auto_time_limit = ref 2500;
val limit = ref 5;
-fun seek_solution int state =
+val _ =
+ ProofGeneralPgip.add_preference Preferences.category_tracing
+ (setmp auto true (fn () =>
+ Preferences.bool_pref auto
+ "auto-solve"
+ "Try to solve newly declared lemmas with existing theorems.") ());
+
+val _ =
+ ProofGeneralPgip.add_preference Preferences.category_tracing
+ (Preferences.nat_pref auto_time_limit
+ "auto-solve-time-limit"
+ "Time limit for seeking automatic solutions (in milliseconds).");
+
+
+(* hook *)
+
+val _ = Context.>> (Specification.add_theorem_hook (fn int => fn state =>
let
val ctxt = Proof.context_of state;
@@ -76,12 +92,10 @@
if int andalso ! auto andalso not (! Toplevel.quiet)
then go ()
else state
- end;
+ end));
end;
-val _ = Context.>> (Specification.add_theorem_hook AutoSolve.seek_solution);
-
val auto_solve = AutoSolve.auto;
val auto_solve_time_limit = AutoSolve.auto_time_limit;
--- a/src/Tools/code/code_funcgr.ML Mon May 11 09:39:53 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,335 +0,0 @@
-(* Title: Tools/code/code_funcgr.ML
- Author: Florian Haftmann, TU Muenchen
-
-Retrieving, normalizing and structuring code equations in graph
-with explicit dependencies.
-
-Legacy. To be replaced by Tools/code/code_wellsorted.ML
-*)
-
-signature CODE_WELLSORTED =
-sig
- type T
- val eqns: T -> string -> (thm * bool) list
- val typ: T -> string -> (string * sort) list * typ
- val all: T -> string list
- val pretty: theory -> T -> Pretty.T
- val make: theory -> string list
- -> ((sort -> sort) * Sorts.algebra) * T
- val eval_conv: theory
- -> (term -> term * (((sort -> sort) * Sorts.algebra) -> T -> thm)) -> cterm -> thm
- val eval_term: theory
- -> (term -> term * (((sort -> sort) * Sorts.algebra) -> T -> 'a)) -> term -> 'a
- val timing: bool ref
-end
-
-structure Code_Wellsorted : CODE_WELLSORTED =
-struct
-
-(** the graph type **)
-
-type T = (((string * sort) list * typ) * (thm * bool) list) Graph.T;
-
-fun eqns funcgr =
- these o Option.map snd o try (Graph.get_node funcgr);
-
-fun typ funcgr =
- fst o Graph.get_node funcgr;
-
-fun all funcgr = Graph.keys funcgr;
-
-fun pretty thy funcgr =
- AList.make (snd o Graph.get_node funcgr) (Graph.keys funcgr)
- |> (map o apfst) (Code_Unit.string_of_const thy)
- |> sort (string_ord o pairself fst)
- |> map (fn (s, thms) =>
- (Pretty.block o Pretty.fbreaks) (
- Pretty.str s
- :: map (Display.pretty_thm o fst) thms
- ))
- |> Pretty.chunks;
-
-
-(** generic combinators **)
-
-fun fold_consts f thms =
- thms
- |> maps (op :: o swap o apfst (snd o strip_comb) o Logic.dest_equals o Thm.plain_prop_of)
- |> (fold o fold_aterms) (fn Const c => f c | _ => I);
-
-fun consts_of (const, []) = []
- | consts_of (const, thms as _ :: _) =
- let
- fun the_const (c, _) = if c = const then I else insert (op =) c
- in fold_consts the_const (map fst thms) [] end;
-
-fun insts_of thy algebra tys sorts =
- let
- fun class_relation (x, _) _ = x;
- fun type_constructor tyco xs class =
- (tyco, class) :: (maps o maps) fst xs;
- fun type_variable (TVar (_, sort)) = map (pair []) sort
- | type_variable (TFree (_, sort)) = map (pair []) sort;
- fun of_sort_deriv ty sort =
- Sorts.of_sort_derivation (Syntax.pp_global thy) algebra
- { class_relation = class_relation, type_constructor = type_constructor,
- type_variable = type_variable }
- (ty, sort) handle Sorts.CLASS_ERROR _ => [] (*permissive!*)
- in (flat o flat) (map2 of_sort_deriv tys sorts) end;
-
-fun meets_of thy algebra =
- let
- fun meet_of ty sort tab =
- Sorts.meet_sort algebra (ty, sort) tab
- handle Sorts.CLASS_ERROR _ => tab (*permissive!*);
- in fold2 meet_of end;
-
-
-(** graph algorithm **)
-
-val timing = ref false;
-
-local
-
-fun resort_thms thy algebra typ_of thms =
- let
- val cs = fold_consts (insert (op =)) thms [];
- fun meets (c, ty) = case typ_of c
- of SOME (vs, _) =>
- meets_of thy algebra (Sign.const_typargs thy (c, ty)) (map snd vs)
- | NONE => I;
- val tab = fold meets cs Vartab.empty;
- in map (Code_Unit.inst_thm thy tab) thms end;
-
-fun resort_eqnss thy algebra funcgr =
- let
- val typ_funcgr = try (fst o Graph.get_node funcgr);
- val resort_dep = (apsnd o burrow_fst) (resort_thms thy algebra typ_funcgr);
- fun resort_rec typ_of (c, []) = (true, (c, []))
- | resort_rec typ_of (c, thms as (thm, _) :: _) = if is_some (AxClass.inst_of_param thy c)
- then (true, (c, thms))
- else let
- val (_, (vs, ty)) = Code_Unit.head_eqn thy thm;
- val thms' as (thm', _) :: _ = burrow_fst (resort_thms thy algebra typ_of) thms
- val (_, (vs', ty')) = Code_Unit.head_eqn thy thm'; (*FIXME simplify check*)
- in (Sign.typ_equiv thy (ty, ty'), (c, thms')) end;
- fun resort_recs eqnss =
- let
- fun typ_of c = case these (AList.lookup (op =) eqnss c)
- of (thm, _) :: _ => (SOME o snd o Code_Unit.head_eqn thy) thm
- | [] => NONE;
- val (unchangeds, eqnss') = split_list (map (resort_rec typ_of) eqnss);
- val unchanged = fold (fn x => fn y => x andalso y) unchangeds true;
- in (unchanged, eqnss') end;
- fun resort_rec_until eqnss =
- let
- val (unchanged, eqnss') = resort_recs eqnss;
- in if unchanged then eqnss' else resort_rec_until eqnss' end;
- in map resort_dep #> resort_rec_until end;
-
-fun instances_of thy algebra insts =
- let
- val thy_classes = (#classes o Sorts.rep_algebra o Sign.classes_of) thy;
- fun all_classparams tyco class =
- these (try (#params o AxClass.get_info thy) class)
- |> map_filter (fn (c, _) => try (AxClass.param_of_inst thy) (c, tyco))
- in
- Symtab.empty
- |> fold (fn (tyco, class) =>
- Symtab.map_default (tyco, []) (insert (op =) class)) insts
- |> (fn tab => Symtab.fold (fn (tyco, classes) => append (maps (all_classparams tyco)
- (Graph.all_succs thy_classes classes))) tab [])
- end;
-
-fun instances_of_consts thy algebra funcgr consts =
- let
- fun inst (cexpr as (c, ty)) = insts_of thy algebra
- (Sign.const_typargs thy (c, ty)) ((map snd o fst) (typ funcgr c));
- in
- []
- |> fold (fold (insert (op =)) o inst) consts
- |> instances_of thy algebra
- end;
-
-fun ensure_const' thy algebra funcgr const auxgr =
- if can (Graph.get_node funcgr) const
- then (NONE, auxgr)
- else if can (Graph.get_node auxgr) const
- then (SOME const, auxgr)
- else if is_some (Code.get_datatype_of_constr thy const) then
- auxgr
- |> Graph.new_node (const, [])
- |> pair (SOME const)
- else let
- val thms = Code.these_eqns thy const
- |> burrow_fst (Code_Unit.norm_args thy)
- |> burrow_fst (Code_Unit.norm_varnames thy Code_Name.purify_tvar Code_Name.purify_var);
- val rhs = consts_of (const, thms);
- in
- auxgr
- |> Graph.new_node (const, thms)
- |> fold_map (ensure_const thy algebra funcgr) rhs
- |-> (fn rhs' => fold (fn SOME const' => Graph.add_edge (const, const')
- | NONE => I) rhs')
- |> pair (SOME const)
- end
-and ensure_const thy algebra funcgr const =
- let
- val timeap = if !timing
- then Output.timeap_msg ("time for " ^ Code_Unit.string_of_const thy const)
- else I;
- in timeap (ensure_const' thy algebra funcgr const) end;
-
-fun merge_eqnss thy algebra raw_eqnss funcgr =
- let
- val eqnss = raw_eqnss
- |> resort_eqnss thy algebra funcgr
- |> filter_out (can (Graph.get_node funcgr) o fst);
- fun typ_eqn c [] = Code.default_typscheme thy c
- | typ_eqn c (thms as (thm, _) :: _) = (snd o Code_Unit.head_eqn thy) thm;
- fun add_eqns (const, thms) =
- Graph.new_node (const, (typ_eqn const thms, thms));
- fun add_deps (eqns as (const, thms)) funcgr =
- let
- val deps = consts_of eqns;
- val insts = instances_of_consts thy algebra funcgr
- (fold_consts (insert (op =)) (map fst thms) []);
- in
- funcgr
- |> ensure_consts thy algebra insts
- |> fold (curry Graph.add_edge const) deps
- |> fold (curry Graph.add_edge const) insts
- end;
- in
- funcgr
- |> fold add_eqns eqnss
- |> fold add_deps eqnss
- end
-and ensure_consts thy algebra cs funcgr =
- let
- val auxgr = Graph.empty
- |> fold (snd oo ensure_const thy algebra funcgr) cs;
- in
- funcgr
- |> fold (merge_eqnss thy algebra)
- (map (AList.make (Graph.get_node auxgr))
- (rev (Graph.strong_conn auxgr)))
- end;
-
-in
-
-(** retrieval interfaces **)
-
-val ensure_consts = ensure_consts;
-
-fun proto_eval thy cterm_of evaluator_lift evaluator proto_ct funcgr =
- let
- val ct = cterm_of proto_ct;
- val _ = Sign.no_vars (Syntax.pp_global thy) (Thm.term_of ct);
- val _ = Term.fold_types (Type.no_tvars #> K I) (Thm.term_of ct) ();
- fun consts_of t =
- fold_aterms (fn Const c_ty => cons c_ty | _ => I) t [];
- val algebra = Code.coregular_algebra thy;
- val thm = Code.preprocess_conv thy ct;
- val ct' = Thm.rhs_of thm;
- val t' = Thm.term_of ct';
- val consts = map fst (consts_of t');
- val funcgr' = ensure_consts thy algebra consts funcgr;
- val (t'', evaluator_funcgr) = evaluator t';
- val consts' = consts_of t'';
- val dicts = instances_of_consts thy algebra funcgr' consts';
- val funcgr'' = ensure_consts thy algebra dicts funcgr';
- in (evaluator_lift (evaluator_funcgr (Code.operational_algebra thy)) thm funcgr'', funcgr'') end;
-
-fun proto_eval_conv thy =
- let
- fun evaluator_lift evaluator thm1 funcgr =
- let
- val thm2 = evaluator funcgr;
- val thm3 = Code.postprocess_conv thy (Thm.rhs_of thm2);
- in
- Thm.transitive thm1 (Thm.transitive thm2 thm3) handle THM _ =>
- error ("could not construct evaluation proof:\n"
- ^ (cat_lines o map Display.string_of_thm) [thm1, thm2, thm3])
- end;
- in proto_eval thy I evaluator_lift end;
-
-fun proto_eval_term thy =
- let
- fun evaluator_lift evaluator _ funcgr = evaluator funcgr;
- in proto_eval thy (Thm.cterm_of thy) evaluator_lift end;
-
-end; (*local*)
-
-structure Funcgr = CodeDataFun
-(
- type T = T;
- val empty = Graph.empty;
- fun purge _ cs funcgr =
- Graph.del_nodes ((Graph.all_preds funcgr
- o filter (can (Graph.get_node funcgr))) cs) funcgr;
-);
-
-fun make thy =
- pair (Code.operational_algebra thy)
- o Funcgr.change thy o ensure_consts thy (Code.coregular_algebra thy);
-
-fun eval_conv thy f =
- fst o Funcgr.change_yield thy o proto_eval_conv thy f;
-
-fun eval_term thy f =
- fst o Funcgr.change_yield thy o proto_eval_term thy f;
-
-
-(** diagnostic commands **)
-
-fun code_depgr thy consts =
- let
- val (_, gr) = make thy consts;
- val select = Graph.all_succs gr consts;
- in
- gr
- |> not (null consts) ? Graph.subgraph (member (op =) select)
- |> Graph.map_nodes ((apsnd o map o apfst) (AxClass.overload thy))
- end;
-
-fun code_thms thy = Pretty.writeln o pretty thy o code_depgr thy;
-
-fun code_deps thy consts =
- let
- val gr = code_depgr thy consts;
- fun mk_entry (const, (_, (_, parents))) =
- let
- val name = Code_Unit.string_of_const thy const;
- val nameparents = map (Code_Unit.string_of_const thy) parents;
- in { name = name, ID = name, dir = "", unfold = true,
- path = "", parents = nameparents }
- end;
- val prgr = Graph.fold ((fn x => fn xs => xs @ [x]) o mk_entry) gr [];
- in Present.display_graph prgr end;
-
-local
-
-structure P = OuterParse
-and K = OuterKeyword
-
-fun code_thms_cmd thy = code_thms thy o op @ o Code_Name.read_const_exprs thy;
-fun code_deps_cmd thy = code_deps thy o op @ o Code_Name.read_const_exprs thy;
-
-in
-
-val _ =
- OuterSyntax.improper_command "code_thms" "print system of code equations for code" OuterKeyword.diag
- (Scan.repeat P.term_group
- >> (fn cs => Toplevel.no_timing o Toplevel.unknown_theory
- o Toplevel.keep ((fn thy => code_thms_cmd thy cs) o Toplevel.theory_of)));
-
-val _ =
- OuterSyntax.improper_command "code_deps" "visualize dependencies of code equations for code" OuterKeyword.diag
- (Scan.repeat P.term_group
- >> (fn cs => Toplevel.no_timing o Toplevel.unknown_theory
- o Toplevel.keep ((fn thy => code_deps_cmd thy cs) o Toplevel.theory_of)));
-
-end;
-
-end; (*struct*)
--- a/src/Tools/code/code_haskell.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Tools/code/code_haskell.ML Mon May 11 17:20:52 2009 +0200
@@ -31,7 +31,7 @@
| pr_bind ((SOME v, SOME p), _) = brackets [str v, str "@", p];
in gen_pr_bind pr_bind pr_term end;
-fun pr_haskell_stmt naming labelled_name syntax_class syntax_tyco syntax_const
+fun pr_haskell_stmt labelled_name syntax_class syntax_tyco syntax_const
init_syms deresolve is_cons contr_classparam_typs deriving_show =
let
val deresolve_base = Long_Name.base_name o deresolve;
@@ -96,7 +96,7 @@
(str o deresolve) c :: map2 pr_term_anno ts_fingerprint (curry Library.take (length ts) tys)
else (str o deresolve) c :: map (pr_term tyvars thm vars BR) ts
end
- and pr_app tyvars = gen_pr_app (pr_app' tyvars) (pr_term tyvars) syntax_const naming
+ and pr_app tyvars = gen_pr_app (pr_app' tyvars) (pr_term tyvars) syntax_const
and pr_bind tyvars = pr_haskell_bind (pr_term tyvars)
and pr_case tyvars thm vars fxy (cases as ((_, [_]), _)) =
let
@@ -261,7 +261,7 @@
val vars = init_syms
|> Code_Printer.intro_vars (the_list const)
|> Code_Printer.intro_vars vs;
- val lhs = IConst (classparam, ([], tys)) `$$ map IVar vs;
+ val lhs = IConst (classparam, (([], []), tys)) `$$ map IVar vs;
(*dictionaries are not relevant at this late stage*)
in
semicolon [
@@ -336,7 +336,7 @@
fun serialize_haskell module_prefix raw_module_name string_classes labelled_name
raw_reserved_names includes raw_module_alias
- syntax_class syntax_tyco syntax_const naming program cs destination =
+ syntax_class syntax_tyco syntax_const program cs destination =
let
val stmt_names = Code_Target.stmt_names_of_destination destination;
val module_name = if null stmt_names then raw_module_name else SOME "Code";
@@ -358,7 +358,7 @@
| deriv' _ (ITyVar _) = true
in deriv [] tyco end;
val reserved_names = Code_Printer.make_vars reserved_names;
- fun pr_stmt qualified = pr_haskell_stmt naming labelled_name
+ fun pr_stmt qualified = pr_haskell_stmt labelled_name
syntax_class syntax_tyco syntax_const reserved_names
(if qualified then deresolver else Long_Name.base_name o deresolver)
is_cons contr_classparam_typs
@@ -469,14 +469,14 @@
| pr_monad pr_bind pr (SOME (bind, false), t) vars = vars
|> pr_bind NOBR bind
|>> (fn p => semicolon [str "let", p, str "=", pr vars NOBR t]);
- fun pretty pr naming thm vars fxy [(t1, _), (t2, _)] = case dest_bind t1 t2
+ fun pretty _ [c_bind'] pr thm vars fxy [(t1, _), (t2, _)] = case dest_bind t1 t2
of SOME (bind, t') => let
- val (binds, t'') = implode_monad ((the o Code_Thingol.lookup_const naming) c_bind) t'
+ val (binds, t'') = implode_monad c_bind' t'
val (ps, vars') = fold_map (pr_monad (pr_haskell_bind (K pr) thm) pr) (bind :: binds) vars;
in (brackify fxy o single o Pretty.enclose "do {" "}" o Pretty.breaks) (ps @| pr vars' NOBR t'') end
| NONE => brackify_infix (1, L) fxy
[pr vars (INFX (1, L)) t1, str ">>=", pr vars (INFX (1, X)) t2]
- in (2, pretty) end;
+ in (2, ([c_bind], pretty)) end;
fun add_monad target' raw_c_bind thy =
let
--- a/src/Tools/code/code_ml.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Tools/code/code_ml.ML Mon May 11 17:20:52 2009 +0200
@@ -6,8 +6,9 @@
signature CODE_ML =
sig
- val eval_term: string * (unit -> 'a) option ref
- -> theory -> term -> string list -> 'a
+ val eval: string option -> string * (unit -> 'a) option ref
+ -> ((term -> term) -> 'a -> 'a) -> theory -> term -> string list -> 'a
+ val target_Eval: string
val setup: theory -> theory
end;
@@ -22,6 +23,7 @@
val target_SML = "SML";
val target_OCaml = "OCaml";
+val target_Eval = "Eval";
datatype ml_stmt =
MLExc of string * int
@@ -43,7 +45,7 @@
(** SML serailizer **)
-fun pr_sml_stmt naming labelled_name syntax_tyco syntax_const reserved_names deresolve is_cons =
+fun pr_sml_stmt labelled_name syntax_tyco syntax_const reserved_names deresolve is_cons =
let
val pr_label_classrel = translate_string (fn "." => "__" | c => c)
o Long_Name.qualifier;
@@ -107,7 +109,7 @@
then pr_case is_closure thm vars fxy cases
else pr_app is_closure thm vars fxy c_ts
| NONE => pr_case is_closure thm vars fxy cases)
- and pr_app' is_closure thm vars (app as ((c, (iss, tys)), ts)) =
+ and pr_app' is_closure thm vars (app as ((c, ((_, iss), tys)), ts)) =
if is_cons c then
let
val k = length tys
@@ -122,7 +124,7 @@
(str o deresolve) c
:: (map (pr_dicts BR) o filter_out null) iss @ map (pr_term is_closure thm vars BR) ts
and pr_app is_closure thm vars = gen_pr_app (pr_app' is_closure) (pr_term is_closure)
- syntax_const naming thm vars
+ syntax_const thm vars
and pr_bind' ((NONE, NONE), _) = str "_"
| pr_bind' ((SOME v, NONE), _) = str v
| pr_bind' ((NONE, SOME p), _) = p
@@ -358,7 +360,7 @@
(** OCaml serializer **)
-fun pr_ocaml_stmt naming labelled_name syntax_tyco syntax_const reserved_names deresolve is_cons =
+fun pr_ocaml_stmt labelled_name syntax_tyco syntax_const reserved_names deresolve is_cons =
let
fun pr_dicts fxy ds =
let
@@ -412,7 +414,7 @@
then pr_case is_closure thm vars fxy cases
else pr_app is_closure thm vars fxy c_ts
| NONE => pr_case is_closure thm vars fxy cases)
- and pr_app' is_closure thm vars (app as ((c, (iss, tys)), ts)) =
+ and pr_app' is_closure thm vars (app as ((c, ((_, iss), tys)), ts)) =
if is_cons c then
if length tys = length ts
then case ts
@@ -426,7 +428,7 @@
else (str o deresolve) c
:: ((map (pr_dicts BR) o filter_out null) iss @ map (pr_term is_closure thm vars BR) ts)
and pr_app is_closure = gen_pr_app (pr_app' is_closure) (pr_term is_closure)
- syntax_const naming
+ syntax_const
and pr_bind' ((NONE, NONE), _) = str "_"
| pr_bind' ((SOME v, NONE), _) = str v
| pr_bind' ((NONE, SOME p), _) = p
@@ -907,36 +909,38 @@
in (deresolver, nodes) end;
fun serialize_ml target compile pr_module pr_stmt raw_module_name labelled_name reserved_names includes raw_module_alias
- _ syntax_tyco syntax_const naming program cs destination =
+ _ syntax_tyco syntax_const program stmt_names destination =
let
val is_cons = Code_Thingol.is_cons program;
- val stmt_names = Code_Target.stmt_names_of_destination destination;
- val module_name = if null stmt_names then raw_module_name else SOME "Code";
+ val present_stmt_names = Code_Target.stmt_names_of_destination destination;
+ val is_present = not (null present_stmt_names);
+ val module_name = if is_present then SOME "Code" else raw_module_name;
val (deresolver, nodes) = ml_node_of_program labelled_name module_name
reserved_names raw_module_alias program;
val reserved_names = Code_Printer.make_vars reserved_names;
fun pr_node prefix (Dummy _) =
NONE
- | pr_node prefix (Stmt (_, stmt)) = if null stmt_names orelse
- (not o null o filter (member (op =) stmt_names) o stmt_names_of) stmt then SOME
- (pr_stmt naming labelled_name syntax_tyco syntax_const reserved_names
+ | pr_node prefix (Stmt (_, stmt)) = if is_present andalso
+ (null o filter (member (op =) present_stmt_names) o stmt_names_of) stmt
+ then NONE
+ else SOME
+ (pr_stmt labelled_name syntax_tyco syntax_const reserved_names
(deresolver prefix) is_cons stmt)
- else NONE
| pr_node prefix (Module (module_name, (_, nodes))) =
separate (str "")
((map_filter (pr_node (prefix @ [module_name]) o Graph.get_node nodes)
o rev o flat o Graph.strong_conn) nodes)
- |> (if null stmt_names then pr_module module_name else Pretty.chunks)
+ |> (if is_present then Pretty.chunks else pr_module module_name)
|> SOME;
- val cs' = (map o try)
- (deresolver (if is_some module_name then the_list module_name else [])) cs;
+ val stmt_names' = (map o try)
+ (deresolver (if is_some module_name then the_list module_name else [])) stmt_names;
val p = Pretty.chunks (separate (str "") (map snd includes @ (map_filter
(pr_node [] o Graph.get_node nodes) o rev o flat o Graph.strong_conn) nodes));
in
Code_Target.mk_serialization target
(case compile of SOME compile => SOME (compile o Code_Target.code_of_pretty) | NONE => NONE)
(fn NONE => Code_Target.code_writeln | SOME file => File.write file o Code_Target.code_of_pretty)
- (rpair cs' o Code_Target.code_of_pretty) p destination
+ (rpair stmt_names' o Code_Target.code_of_pretty) p destination
end;
end; (*local*)
@@ -944,20 +948,17 @@
(** ML (system language) code for evaluation and instrumentalization **)
-fun ml_code_of thy = Code_Target.serialize_custom thy (target_SML,
+fun eval_code_of some_target thy = Code_Target.serialize_custom thy (the_default target_Eval some_target,
(fn _ => fn [] => serialize_ml target_SML (SOME (K ())) (K Pretty.chunks) pr_sml_stmt (SOME ""),
literals_sml));
(* evaluation *)
-fun eval eval'' term_of reff thy ct args =
+fun eval some_target reff postproc thy t args =
let
val ctxt = ProofContext.init thy;
- val _ = if null (Term.add_frees (term_of ct) []) then () else error ("Term "
- ^ quote (Syntax.string_of_term_global thy (term_of ct))
- ^ " to be evaluated contains free variables");
- fun eval' naming program ((vs, ty), t) deps =
+ fun evaluator naming program ((_, (_, ty)), t) deps =
let
val _ = if Code_Thingol.contains_dictvar t then
error "Term to be evaluated contains free dictionaries" else ();
@@ -966,13 +967,11 @@
|> Graph.new_node (value_name,
Code_Thingol.Fun (Term.dummy_patternN, (([], ty), [(([], t), (Drule.dummy_thm, true))])))
|> fold (curry Graph.add_edge value_name) deps;
- val (value_code, [SOME value_name']) = ml_code_of thy naming program' [value_name];
+ val (value_code, [SOME value_name']) = eval_code_of some_target thy naming program' [value_name];
val sml_code = "let\n" ^ value_code ^ "\nin " ^ value_name'
^ space_implode " " (map (enclose "(" ")") args) ^ " end";
in ML_Context.evaluate ctxt false reff sml_code end;
- in eval'' thy (rpair eval') ct end;
-
-fun eval_term reff = eval Code_Thingol.eval_term I reff;
+ in Code_Thingol.eval thy I postproc evaluator t end;
(* instrumentalization by antiquotation *)
@@ -981,42 +980,69 @@
structure CodeAntiqData = ProofDataFun
(
- type T = string list * (bool * (string * (string * (string * string) list) lazy));
- fun init _ = ([], (true, ("", Lazy.value ("", []))));
+ type T = (string list * string list) * (bool * (string
+ * (string * ((string * string) list * (string * string) list)) lazy));
+ fun init _ = (([], []), (true, ("", Lazy.value ("", ([], [])))));
);
val is_first_occ = fst o snd o CodeAntiqData.get;
-fun delayed_code thy consts () =
+fun delayed_code thy tycos consts () =
let
val (consts', (naming, program)) = Code_Thingol.consts_program thy consts;
- val (ml_code, consts'') = ml_code_of thy naming program consts';
- val const_tab = map2 (fn const => fn NONE =>
- error ("Constant " ^ (quote o Code_Unit.string_of_const thy) const
- ^ "\nhas a user-defined serialization")
- | SOME const' => (const, const')) consts consts''
- in (ml_code, const_tab) end;
+ val tycos' = map (the o Code_Thingol.lookup_tyco naming) tycos;
+ val (ml_code, target_names) = eval_code_of NONE thy naming program (consts' @ tycos');
+ val (consts'', tycos'') = chop (length consts') target_names;
+ val consts_map = map2 (fn const => fn NONE =>
+ error ("Constant " ^ (quote o Code_Unit.string_of_const thy) const
+ ^ "\nhas a user-defined serialization")
+ | SOME const'' => (const, const'')) consts consts''
+ val tycos_map = map2 (fn tyco => fn NONE =>
+ error ("Type " ^ (quote o Sign.extern_type thy) tyco
+ ^ "\nhas a user-defined serialization")
+ | SOME tyco'' => (tyco, tyco'')) tycos tycos'';
+ in (ml_code, (tycos_map, consts_map)) end;
-fun register_const const ctxt =
+fun register_code new_tycos new_consts ctxt =
let
- val (consts, (_, (struct_name, _))) = CodeAntiqData.get ctxt;
- val consts' = insert (op =) const consts;
+ val ((tycos, consts), (_, (struct_name, _))) = CodeAntiqData.get ctxt;
+ val tycos' = fold (insert (op =)) new_tycos tycos;
+ val consts' = fold (insert (op =)) new_consts consts;
val (struct_name', ctxt') = if struct_name = ""
then ML_Antiquote.variant "Code" ctxt
else (struct_name, ctxt);
- val acc_code = Lazy.lazy (delayed_code (ProofContext.theory_of ctxt) consts');
- in CodeAntiqData.put (consts', (false, (struct_name', acc_code))) ctxt' end;
+ val acc_code = Lazy.lazy (delayed_code (ProofContext.theory_of ctxt) tycos' consts');
+ in CodeAntiqData.put ((tycos', consts'), (false, (struct_name', acc_code))) ctxt' end;
+
+fun register_const const = register_code [] [const];
-fun print_code struct_name is_first const ctxt =
+fun register_datatype tyco constrs = register_code [tyco] constrs;
+
+fun print_const const all_struct_name tycos_map consts_map =
+ (Long_Name.append all_struct_name o the o AList.lookup (op =) consts_map) const;
+
+fun print_datatype tyco constrs all_struct_name tycos_map consts_map =
let
- val (consts, (_, (struct_code_name, acc_code))) = CodeAntiqData.get ctxt;
- val (raw_ml_code, consts_map) = Lazy.force acc_code;
- val const'' = Long_Name.append (Long_Name.append struct_name struct_code_name)
- ((the o AList.lookup (op =) consts_map) const);
+ val upperize = implode o nth_map 0 Symbol.to_ascii_upper o explode;
+ fun check_base name name'' =
+ if upperize (Long_Name.base_name name) = upperize name''
+ then () else error ("Name as printed " ^ quote name''
+ ^ "\ndiffers from logical base name " ^ quote (Long_Name.base_name name) ^ "; sorry.");
+ val tyco'' = (the o AList.lookup (op =) tycos_map) tyco;
+ val constrs'' = map (the o AList.lookup (op =) consts_map) constrs;
+ val _ = check_base tyco tyco'';
+ val _ = map2 check_base constrs constrs'';
+ in "datatype " ^ tyco'' ^ " = datatype " ^ Long_Name.append all_struct_name tyco'' end;
+
+fun print_code struct_name is_first print_it ctxt =
+ let
+ val (_, (_, (struct_code_name, acc_code))) = CodeAntiqData.get ctxt;
+ val (raw_ml_code, (tycos_map, consts_map)) = Lazy.force acc_code;
val ml_code = if is_first then "\nstructure " ^ struct_code_name
^ " =\nstruct\n\n" ^ raw_ml_code ^ "\nend;\n\n"
else "";
- in (ml_code, const'') end;
+ val all_struct_name = Long_Name.append struct_name struct_code_name;
+ in (ml_code, print_it all_struct_name tycos_map consts_map) end;
in
@@ -1025,7 +1051,19 @@
val const = Code_Unit.check_const (ProofContext.theory_of background) raw_const;
val is_first = is_first_occ background;
val background' = register_const const background;
- in (print_code struct_name is_first const, background') end;
+ in (print_code struct_name is_first (print_const const), background') end;
+
+fun ml_code_datatype_antiq (raw_tyco, raw_constrs) {struct_name, background} =
+ let
+ val thy = ProofContext.theory_of background;
+ val tyco = Sign.intern_type thy raw_tyco;
+ val constrs = map (Code_Unit.check_const thy) raw_constrs;
+ val constrs' = (map fst o snd o Code.get_datatype thy) tyco;
+ val _ = if gen_eq_set (op =) (constrs, constrs') then ()
+ else error ("Type " ^ quote tyco ^ ": given constructors diverge from real constructors")
+ val is_first = is_first_occ background;
+ val background' = register_datatype tyco constrs background;
+ in (print_code struct_name is_first (print_datatype tyco constrs), background') end;
end; (*local*)
@@ -1033,6 +1071,10 @@
(** Isar setup **)
val _ = ML_Context.add_antiq "code" (fn _ => Args.term >> ml_code_antiq);
+val _ = ML_Context.add_antiq "code_datatype" (fn _ =>
+ (Args.tyname --| Scan.lift (Args.$$$ "=")
+ -- (Args.term ::: Scan.repeat (Scan.lift (Args.$$$ "|") |-- Args.term)))
+ >> ml_code_datatype_antiq);
fun isar_seri_sml module_name =
Code_Target.parse_args (Scan.succeed ())
@@ -1048,6 +1090,7 @@
val setup =
Code_Target.add_target (target_SML, (isar_seri_sml, literals_sml))
#> Code_Target.add_target (target_OCaml, (isar_seri_ocaml, literals_ocaml))
+ #> Code_Target.extend_target (target_Eval, (target_SML, K I))
#> Code_Target.add_syntax_tyco target_SML "fun" (SOME (2, fn pr_typ => fn fxy => fn [ty1, ty2] =>
brackify_infix (1, R) fxy [
pr_typ (INFX (1, X)) ty1,
--- a/src/Tools/code/code_name.ML Mon May 11 09:39:53 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-(* Title: Tools/code/code_name.ML
- Author: Florian Haftmann, TU Muenchen
-
-Some code generator infrastructure concerning names.
-*)
-
-signature CODE_NAME =
-sig
- val purify_var: string -> string
- val purify_tvar: string -> string
- val purify_base: string -> string
- val check_modulename: string -> string
-
- val read_const_exprs: theory -> string list -> string list * string list
-end;
-
-structure Code_Name: CODE_NAME =
-struct
-
-(** purification **)
-
-fun purify_name upper =
- let
- fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s orelse s = "'";
- val is_junk = not o is_valid andf Symbol.is_regular;
- val junk = Scan.many is_junk;
- val scan_valids = Symbol.scanner "Malformed input"
- ((junk |--
- (Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.many is_valid >> implode)
- --| junk))
- ::: Scan.repeat ((Scan.many1 is_valid >> implode) --| junk));
- fun upper_lower cs = if upper then nth_map 0 Symbol.to_ascii_upper cs
- else (if forall Symbol.is_ascii_upper cs
- then map else nth_map 0) Symbol.to_ascii_lower cs;
- in
- explode
- #> scan_valids
- #> space_implode "_"
- #> explode
- #> upper_lower
- #> implode
- end;
-
-fun purify_var "" = "x"
- | purify_var v = purify_name false v;
-
-fun purify_tvar "" = "'a"
- | purify_tvar v =
- (unprefix "'" #> explode #> filter Symbol.is_ascii_letter #> cons "'" #> implode) v;
-
-val purify_prefix =
- explode
- (*FIMXE should disappear as soon as hierarchical theory name spaces are available*)
- #> Symbol.scanner "Malformed name"
- (Scan.repeat ($$ "_" |-- $$ "_" >> (fn _ => ".") || Scan.one Symbol.is_regular))
- #> implode
- #> Long_Name.explode
- #> map (purify_name true);
-
-(*FIMXE non-canonical function treating non-canonical names*)
-fun purify_base "op &" = "and"
- | purify_base "op |" = "or"
- | purify_base "op -->" = "implies"
- | purify_base "op :" = "member"
- | purify_base "*" = "product"
- | purify_base "+" = "sum"
- | purify_base s = if String.isPrefix "op =" s
- then "eq" ^ purify_name false s
- else purify_name false s;
-
-fun check_modulename mn =
- let
- val mns = Long_Name.explode mn;
- val mns' = map (purify_name true) mns;
- in
- if mns' = mns then mn else error ("Invalid module name: " ^ quote mn ^ "\n"
- ^ "perhaps try " ^ quote (Long_Name.implode mns'))
- end;
-
-
-(** misc **)
-
-fun read_const_exprs thy =
- let
- fun consts_of some_thyname =
- let
- val thy' = case some_thyname
- of SOME thyname => ThyInfo.the_theory thyname thy
- | NONE => thy;
- val cs = Symtab.fold (fn (c, (_, NONE)) => cons c | _ => I)
- ((snd o #constants o Consts.dest o #consts o Sign.rep_sg) thy') [];
- fun belongs_here c =
- not (exists (fn thy'' => Sign.declared_const thy'' c) (Theory.parents_of thy'))
- in case some_thyname
- of NONE => cs
- | SOME thyname => filter belongs_here cs
- end;
- fun read_const_expr "*" = ([], consts_of NONE)
- | read_const_expr s = if String.isSuffix ".*" s
- then ([], consts_of (SOME (unsuffix ".*" s)))
- else ([Code_Unit.read_const thy s], []);
- in pairself flat o split_list o map read_const_expr end;
-
-end;
--- a/src/Tools/code/code_printer.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Tools/code/code_printer.ML Mon May 11 17:20:52 2009 +0200
@@ -23,6 +23,17 @@
val intro_vars: string list -> var_ctxt -> var_ctxt
val lookup_var: var_ctxt -> string -> string
+ type literals
+ val Literals: { literal_char: string -> string, literal_string: string -> string,
+ literal_numeral: bool -> int -> string,
+ literal_list: Pretty.T list -> Pretty.T, infix_cons: int * string }
+ -> literals
+ val literal_char: literals -> string -> string
+ val literal_string: literals -> string -> string
+ val literal_numeral: literals -> bool -> int -> string
+ val literal_list: literals -> Pretty.T list -> Pretty.T
+ val infix_cons: literals -> int * string
+
type lrx
val L: lrx
val R: lrx
@@ -41,6 +52,7 @@
type dict = Code_Thingol.dict
type tyco_syntax
type const_syntax
+ type proto_const_syntax
val parse_infix: ('a -> 'b) -> lrx * int -> string
-> int * ((fixity -> 'b -> Pretty.T)
-> fixity -> 'a list -> Pretty.T)
@@ -48,26 +60,18 @@
-> (int * ((fixity -> 'b -> Pretty.T)
-> fixity -> 'a list -> Pretty.T)) option * OuterParse.token list
val simple_const_syntax: (int * ((fixity -> iterm -> Pretty.T)
- -> fixity -> (iterm * itype) list -> Pretty.T)) option -> const_syntax option
+ -> fixity -> (iterm * itype) list -> Pretty.T)) option -> proto_const_syntax option
+ val activate_const_syntax: theory -> literals
+ -> proto_const_syntax -> Code_Thingol.naming -> const_syntax * Code_Thingol.naming
val gen_pr_app: (thm -> var_ctxt -> const * iterm list -> Pretty.T list)
-> (thm -> var_ctxt -> fixity -> iterm -> Pretty.T)
- -> (string -> const_syntax option) -> Code_Thingol.naming
+ -> (string -> const_syntax option)
-> thm -> var_ctxt -> fixity -> const * iterm list -> Pretty.T
val gen_pr_bind: ((string option * Pretty.T option) * itype -> Pretty.T)
-> (thm -> var_ctxt -> fixity -> iterm -> Pretty.T)
-> thm -> fixity
-> (string option * iterm option) * itype -> var_ctxt -> Pretty.T * var_ctxt
- type literals
- val Literals: { literal_char: string -> string, literal_string: string -> string,
- literal_numeral: bool -> int -> string, literal_list: Pretty.T list -> Pretty.T, infix_cons: int * string }
- -> literals
- val literal_char: literals -> string -> string
- val literal_string: literals -> string -> string
- val literal_numeral: literals -> bool -> int -> string
- val literal_list: literals -> Pretty.T list -> Pretty.T
- val infix_cons: literals -> int * string
-
val mk_name_module: Name.context -> string option -> (string -> string option)
-> 'a Graph.T -> string -> string
val dest_name: string -> string * string
@@ -115,6 +119,25 @@
val first_lower = implode o nth_map 0 Symbol.to_ascii_lower o explode;
+(** pretty literals **)
+
+datatype literals = Literals of {
+ literal_char: string -> string,
+ literal_string: string -> string,
+ literal_numeral: bool -> int -> string,
+ literal_list: Pretty.T list -> Pretty.T,
+ infix_cons: int * string
+};
+
+fun dest_Literals (Literals lits) = lits;
+
+val literal_char = #literal_char o dest_Literals;
+val literal_string = #literal_string o dest_Literals;
+val literal_numeral = #literal_numeral o dest_Literals;
+val literal_list = #literal_list o dest_Literals;
+val infix_cons = #infix_cons o dest_Literals;
+
+
(** syntax printer **)
(* binding priorities *)
@@ -158,17 +181,25 @@
type tyco_syntax = int * ((fixity -> itype -> Pretty.T)
-> fixity -> itype list -> Pretty.T);
type const_syntax = int * ((var_ctxt -> fixity -> iterm -> Pretty.T)
- -> Code_Thingol.naming -> thm -> var_ctxt -> fixity -> (iterm * itype) list -> Pretty.T);
+ -> thm -> var_ctxt -> fixity -> (iterm * itype) list -> Pretty.T);
+type proto_const_syntax = int * (string list * (literals -> string list
+ -> (var_ctxt -> fixity -> iterm -> Pretty.T)
+ -> thm -> var_ctxt -> fixity -> (iterm * itype) list -> Pretty.T));
-fun simple_const_syntax x = (Option.map o apsnd)
- (fn pretty => fn pr => fn naming => fn thm => fn vars => pretty (pr vars)) x;
+fun simple_const_syntax (SOME (n, f)) = SOME (n,
+ ([], (fn _ => fn _ => fn pr => fn thm => fn vars => f (pr vars))))
+ | simple_const_syntax NONE = NONE;
-fun gen_pr_app pr_app pr_term syntax_const naming thm vars fxy (app as ((c, (_, tys)), ts)) =
+fun activate_const_syntax thy literals (n, (cs, f)) naming =
+ fold_map (Code_Thingol.ensure_declared_const thy) cs naming
+ |-> (fn cs' => pair (n, f literals cs'));
+
+fun gen_pr_app pr_app pr_term syntax_const thm vars fxy (app as ((c, (_, tys)), ts)) =
case syntax_const c
of NONE => brackify fxy (pr_app thm vars app)
| SOME (k, pr) =>
let
- fun pr' fxy ts = pr (pr_term thm) naming thm vars fxy (ts ~~ curry Library.take k tys);
+ fun pr' fxy ts = pr (pr_term thm) thm vars fxy (ts ~~ curry Library.take k tys);
in if k = length ts
then pr' fxy ts
else if k < length ts
@@ -253,25 +284,6 @@
val _ = List.app OuterKeyword.keyword [infixK, infixlK, infixrK];
-(** pretty literals **)
-
-datatype literals = Literals of {
- literal_char: string -> string,
- literal_string: string -> string,
- literal_numeral: bool -> int -> string,
- literal_list: Pretty.T list -> Pretty.T,
- infix_cons: int * string
-};
-
-fun dest_Literals (Literals lits) = lits;
-
-val literal_char = #literal_char o dest_Literals;
-val literal_string = #literal_string o dest_Literals;
-val literal_numeral = #literal_numeral o dest_Literals;
-val literal_list = #literal_list o dest_Literals;
-val infix_cons = #infix_cons o dest_Literals;
-
-
(** module name spaces **)
val dest_name =
--- a/src/Tools/code/code_target.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Tools/code/code_target.ML Mon May 11 17:20:52 2009 +0200
@@ -44,7 +44,7 @@
val add_syntax_class: string -> class -> string option -> theory -> theory
val add_syntax_inst: string -> string * class -> bool -> theory -> theory
val add_syntax_tyco: string -> string -> tyco_syntax option -> theory -> theory
- val add_syntax_const: string -> string -> const_syntax option -> theory -> theory
+ val add_syntax_const: string -> string -> proto_const_syntax option -> theory -> theory
val add_reserved: string -> string -> theory -> theory
end;
@@ -68,7 +68,7 @@
fun compile f = (code_setmp f Compile; ());
fun export f = (code_setmp f Export; ());
fun file p f = (code_setmp f (File p); ());
-fun string cs f = fst (the (code_setmp f (String cs)));
+fun string stmts f = fst (the (code_setmp f (String stmts)));
fun stmt_names_of_destination (String stmts) = stmts
| stmt_names_of_destination _ = [];
@@ -86,7 +86,7 @@
class: string Symtab.table,
instance: unit Symreltab.table,
tyco: tyco_syntax Symtab.table,
- const: const_syntax Symtab.table
+ const: proto_const_syntax Symtab.table
};
fun mk_name_syntax_table ((class, instance), (tyco, const)) =
@@ -112,7 +112,6 @@
-> (string -> string option) (*class syntax*)
-> (string -> tyco_syntax option)
-> (string -> const_syntax option)
- -> Code_Thingol.naming
-> Code_Thingol.program
-> string list (*selected statements*)
-> serialization;
@@ -323,8 +322,15 @@
val add_include = gen_add_include Code_Unit.check_const;
val add_include_cmd = gen_add_include Code_Unit.read_const;
-fun add_module_alias target =
- map_module_alias target o Symtab.update o apsnd Code_Name.check_modulename;
+fun add_module_alias target (thyname, modlname) =
+ let
+ val xs = Long_Name.explode modlname;
+ val xs' = map (Name.desymbolize true) xs;
+ in if xs' = xs
+ then map_module_alias target (Symtab.update (thyname, modlname))
+ else error ("Invalid module name: " ^ quote modlname ^ "\n"
+ ^ "perhaps try " ^ quote (Long_Name.implode xs'))
+ end;
fun gen_allow_abort prep_const raw_c thy =
let
@@ -395,19 +401,34 @@
val Code_Thingol.Datatype (tyco, _) = Graph.get_node program tyco
in quote (Sign.extern_type thy tyco ^ " :: " ^ Sign.extern_class thy class) end
-fun invoke_serializer thy abortable serializer reserved abs_includes
+fun activate_syntax lookup_name src_tab = Symtab.empty
+ |> fold_map (fn thing_identifier => fn tab => case lookup_name thing_identifier
+ of SOME name => (SOME name,
+ Symtab.update_new (name, the (Symtab.lookup src_tab thing_identifier)) tab)
+ | NONE => (NONE, tab)) (Symtab.keys src_tab)
+ |>> map_filter I;
+
+fun activate_const_syntax thy literals src_tab naming = (Symtab.empty, naming)
+ |> fold_map (fn thing_identifier => fn (tab, naming) =>
+ case Code_Thingol.lookup_const naming thing_identifier
+ of SOME name => let
+ val (syn, naming') = Code_Printer.activate_const_syntax thy
+ literals (the (Symtab.lookup src_tab thing_identifier)) naming
+ in (SOME name, (Symtab.update_new (name, syn) tab, naming')) end
+ | NONE => (NONE, (tab, naming))) (Symtab.keys src_tab)
+ |>> map_filter I;
+
+fun invoke_serializer thy abortable serializer literals reserved abs_includes
module_alias class instance tyco const module args naming program2 names1 =
let
- fun distill_names lookup_name src_tab = Symtab.empty
- |> fold_map (fn thing_identifier => fn tab => case lookup_name naming thing_identifier
- of SOME name => (SOME name, Symtab.update_new (name, the (Symtab.lookup src_tab thing_identifier)) tab)
- | NONE => (NONE, tab)) (Symtab.keys src_tab)
- |>> map_filter I;
- val (names_class, class') = distill_names Code_Thingol.lookup_class class;
+ val (names_class, class') =
+ activate_syntax (Code_Thingol.lookup_class naming) class;
val names_inst = map_filter (Code_Thingol.lookup_instance naming)
(Symreltab.keys instance);
- val (names_tyco, tyco') = distill_names Code_Thingol.lookup_tyco tyco;
- val (names_const, const') = distill_names Code_Thingol.lookup_const const;
+ val (names_tyco, tyco') =
+ activate_syntax (Code_Thingol.lookup_tyco naming) tyco;
+ val (names_const, (const', _)) =
+ activate_const_syntax thy literals const naming;
val names_hidden = names_class @ names_inst @ names_tyco @ names_const;
val names2 = subtract (op =) names_hidden names1;
val program3 = Graph.subgraph (not o member (op =) names_hidden) program2;
@@ -422,7 +443,7 @@
serializer module args (labelled_name thy program2) reserved includes
(Symtab.lookup module_alias) (Symtab.lookup class')
(Symtab.lookup tyco') (Symtab.lookup const')
- naming program4 names2
+ program4 names2
end;
fun mount_serializer thy alt_serializer target module args naming program names =
@@ -453,8 +474,9 @@
((Symtab.dest o the_includes) data);
val module_alias = the_module_alias data;
val { class, instance, tyco, const } = the_name_syntax data;
+ val literals = the_literals thy target;
in
- invoke_serializer thy abortable serializer reserved
+ invoke_serializer thy abortable serializer literals reserved
includes module_alias class instance tyco const module args naming (modify program) names
end;
@@ -495,7 +517,7 @@
fun read_const_exprs thy cs =
let
- val (cs1, cs2) = Code_Name.read_const_exprs thy cs;
+ val (cs1, cs2) = Code_Thingol.read_const_exprs thy cs;
val (names3, (naming, program)) = Code_Thingol.consts_program thy cs2;
val names4 = transitivly_non_empty_funs thy naming program;
val cs5 = map_filter
--- a/src/Tools/code/code_thingol.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Tools/code/code_thingol.ML Mon May 11 17:20:52 2009 +0200
@@ -20,7 +20,7 @@
datatype itype =
`%% of string * itype list
| ITyVar of vname;
- type const = string * (dict list list * itype list (*types of arguments*))
+ type const = string * ((itype list * dict list list) * itype list (*types of arguments*))
datatype iterm =
IConst of const
| IVar of vname
@@ -44,11 +44,10 @@
val unfold_abs: iterm -> ((vname * iterm option) * itype) list * iterm
val split_let: iterm -> (((iterm * itype) * iterm) * iterm) option
val unfold_let: iterm -> ((iterm * itype) * iterm) list * iterm
- val unfold_const_app: iterm ->
- ((string * (dict list list * itype list)) * iterm list) option
+ val unfold_const_app: iterm -> (const * iterm list) option
val collapse_let: ((vname * itype) * iterm) * iterm
-> (iterm * itype) * (iterm * iterm) list
- val eta_expand: int -> (string * (dict list list * itype list)) * iterm list -> iterm
+ val eta_expand: int -> const * iterm list -> iterm
val contains_dictvar: iterm -> bool
val locally_monomorphic: iterm -> bool
val fold_constnames: (string -> 'a -> 'a) -> iterm -> 'a -> 'a
@@ -62,6 +61,7 @@
val lookup_tyco: naming -> string -> string option
val lookup_instance: naming -> class * string -> string option
val lookup_const: naming -> string -> string option
+ val ensure_declared_const: theory -> string -> naming -> string * naming
datatype stmt =
NoStmt
@@ -81,13 +81,14 @@
val is_cons: program -> string -> bool
val contr_classparam_typs: program -> string -> itype option list
+ val read_const_exprs: theory -> string list -> string list * string list
val consts_program: theory -> string list -> string list * (naming * program)
val cached_program: theory -> naming * program
- val eval_conv: theory
- -> (term -> term * (naming -> program -> typscheme * iterm -> string list -> thm))
+ val eval_conv: theory -> (sort -> sort)
+ -> (naming -> program -> ((string * sort) list * typscheme) * iterm -> string list -> cterm -> thm)
-> cterm -> thm
- val eval_term: theory
- -> (term -> term * (naming -> program -> typscheme * iterm -> string list -> 'a))
+ val eval: theory -> (sort -> sort) -> ((term -> term) -> 'a -> 'a)
+ -> (naming -> program -> ((string * sort) list * typscheme) * iterm -> string list -> 'a)
-> term -> 'a
end;
@@ -121,7 +122,7 @@
`%% of string * itype list
| ITyVar of vname;
-type const = string * (dict list list * itype list (*types of arguments*))
+type const = string * ((itype list * dict list list) * itype list (*types of arguments*))
datatype iterm =
IConst of const
@@ -211,7 +212,7 @@
| contains (DictVar _) = K true;
in
fold_aiterms
- (fn IConst (_, (dss, _)) => (fold o fold) contains dss | _ => I) t false
+ (fn IConst (_, ((_, dss), _)) => (fold o fold) contains dss | _ => I) t false
end;
fun locally_monomorphic (IConst _) = false
@@ -239,10 +240,18 @@
| NONE => (case Code.get_datatype_of_constr thy c
of SOME dtco => thyname_of_tyco thy dtco
| NONE => thyname_of thy (Consts.the_tags (Sign.consts_of thy)) c);
+ fun purify_base "op &" = "and"
+ | purify_base "op |" = "or"
+ | purify_base "op -->" = "implies"
+ | purify_base "op :" = "member"
+ | purify_base "op =" = "eq"
+ | purify_base "*" = "product"
+ | purify_base "+" = "sum"
+ | purify_base s = Name.desymbolize false s;
fun namify thy get_basename get_thyname name =
let
val prefix = get_thyname thy name;
- val base = (Code_Name.purify_base o get_basename) name;
+ val base = (purify_base o get_basename) name;
in Long_Name.append prefix base end;
in
@@ -351,6 +360,11 @@
fun declare_const thy = declare thy map_const
lookup_const Symtab.update_new namify_const;
+fun ensure_declared_const thy const naming =
+ case lookup_const naming const
+ of SOME const' => (const', naming)
+ | NONE => declare_const thy const naming;
+
val unfold_fun = unfoldr
(fn "Pure.fun.tyco" `%% [ty1, ty2] => SOME (ty1, ty2)
| _ => NONE); (*depends on suffix_tyco and namify_tyco!*)
@@ -459,7 +473,45 @@
(* translation *)
-fun ensure_class thy (algbr as (_, algebra)) funcgr class =
+fun ensure_tyco thy algbr funcgr tyco =
+ let
+ val stmt_datatype =
+ let
+ val (vs, cos) = Code.get_datatype thy tyco;
+ in
+ fold_map (translate_tyvar_sort thy algbr funcgr) vs
+ ##>> fold_map (fn (c, tys) =>
+ ensure_const thy algbr funcgr c
+ ##>> fold_map (translate_typ thy algbr funcgr) tys) cos
+ #>> (fn info => Datatype (tyco, info))
+ end;
+ in ensure_stmt lookup_tyco (declare_tyco thy) stmt_datatype tyco end
+and ensure_const thy algbr funcgr c =
+ let
+ fun stmt_datatypecons tyco =
+ ensure_tyco thy algbr funcgr tyco
+ #>> (fn tyco => Datatypecons (c, tyco));
+ fun stmt_classparam class =
+ ensure_class thy algbr funcgr class
+ #>> (fn class => Classparam (c, class));
+ fun stmt_fun ((vs, ty), raw_thms) =
+ let
+ val thms = if null (Term.add_tfreesT ty []) orelse (null o fst o strip_type) ty
+ then raw_thms
+ else (map o apfst) (Code_Unit.expand_eta thy 1) raw_thms;
+ in
+ fold_map (translate_tyvar_sort thy algbr funcgr) vs
+ ##>> translate_typ thy algbr funcgr ty
+ ##>> fold_map (translate_eq thy algbr funcgr) thms
+ #>> (fn info => Fun (c, info))
+ end;
+ val stmt_const = case Code.get_datatype_of_constr thy c
+ of SOME tyco => stmt_datatypecons tyco
+ | NONE => (case AxClass.class_of_param thy c
+ of SOME class => stmt_classparam class
+ | NONE => stmt_fun (Code_Wellsorted.typ funcgr c, Code_Wellsorted.eqns funcgr c))
+ in ensure_stmt lookup_const (declare_const thy) stmt_const c end
+and ensure_class thy (algbr as (_, algebra)) funcgr class =
let
val superclasses = (Sorts.minimize_sort algebra o Sorts.super_classes algebra) class;
val cs = #params (AxClass.get_info thy class);
@@ -477,65 +529,6 @@
##>> ensure_class thy algbr funcgr superclass
#>> Classrel;
in ensure_stmt lookup_classrel (declare_classrel thy) stmt_classrel (subclass, superclass) end
-and ensure_tyco thy algbr funcgr tyco =
- let
- val stmt_datatype =
- let
- val (vs, cos) = Code.get_datatype thy tyco;
- in
- fold_map (translate_tyvar_sort thy algbr funcgr) vs
- ##>> fold_map (fn (c, tys) =>
- ensure_const thy algbr funcgr c
- ##>> fold_map (translate_typ thy algbr funcgr) tys) cos
- #>> (fn info => Datatype (tyco, info))
- end;
- in ensure_stmt lookup_tyco (declare_tyco thy) stmt_datatype tyco end
-and translate_tyvar_sort thy (algbr as (proj_sort, _)) funcgr (v, sort) =
- fold_map (ensure_class thy algbr funcgr) (proj_sort sort)
- #>> (fn sort => (unprefix "'" v, sort))
-and translate_typ thy algbr funcgr (TFree (v, _)) =
- pair (ITyVar (unprefix "'" v))
- | translate_typ thy algbr funcgr (Type (tyco, tys)) =
- ensure_tyco thy algbr funcgr tyco
- ##>> fold_map (translate_typ thy algbr funcgr) tys
- #>> (fn (tyco, tys) => tyco `%% tys)
-and translate_dicts thy (algbr as (proj_sort, algebra)) funcgr thm (ty, sort) =
- let
- val pp = Syntax.pp_global thy;
- datatype typarg =
- Global of (class * string) * typarg list list
- | Local of (class * class) list * (string * (int * sort));
- fun class_relation (Global ((_, tyco), yss), _) class =
- Global ((class, tyco), yss)
- | class_relation (Local (classrels, v), subclass) superclass =
- Local ((subclass, superclass) :: classrels, v);
- fun type_constructor tyco yss class =
- Global ((class, tyco), (map o map) fst yss);
- fun type_variable (TFree (v, sort)) =
- let
- val sort' = proj_sort sort;
- in map_index (fn (n, class) => (Local ([], (v, (n, sort'))), class)) sort' end;
- val typargs = Sorts.of_sort_derivation pp algebra
- {class_relation = class_relation, type_constructor = type_constructor,
- type_variable = type_variable} (ty, proj_sort sort)
- handle Sorts.CLASS_ERROR e => not_wellsorted thy thm ty sort e;
- fun mk_dict (Global (inst, yss)) =
- ensure_inst thy algbr funcgr inst
- ##>> (fold_map o fold_map) mk_dict yss
- #>> (fn (inst, dss) => DictConst (inst, dss))
- | mk_dict (Local (classrels, (v, (k, sort)))) =
- fold_map (ensure_classrel thy algbr funcgr) classrels
- #>> (fn classrels => DictVar (classrels, (unprefix "'" v, (k, length sort))))
- in fold_map mk_dict typargs end
-and translate_eq thy algbr funcgr (thm, linear) =
- let
- val (args, rhs) = (apfst (snd o strip_comb) o Logic.dest_equals
- o Logic.unvarify o prop_of) thm;
- in
- fold_map (translate_term thy algbr funcgr (SOME thm)) args
- ##>> translate_term thy algbr funcgr (SOME thm) rhs
- #>> rpair (thm, linear)
- end
and ensure_inst thy (algbr as (_, algebra)) funcgr (class, tyco) =
let
val superclasses = (Sorts.minimize_sort algebra o Sorts.super_classes algebra) class;
@@ -572,31 +565,12 @@
#>> (fn ((((class, tyco), arity), superarities), classparams) =>
Classinst ((class, (tyco, arity)), (superarities, classparams)));
in ensure_stmt lookup_instance (declare_instance thy) stmt_inst (class, tyco) end
-and ensure_const thy algbr funcgr c =
- let
- fun stmt_datatypecons tyco =
+and translate_typ thy algbr funcgr (TFree (v, _)) =
+ pair (ITyVar (unprefix "'" v))
+ | translate_typ thy algbr funcgr (Type (tyco, tys)) =
ensure_tyco thy algbr funcgr tyco
- #>> (fn tyco => Datatypecons (c, tyco));
- fun stmt_classparam class =
- ensure_class thy algbr funcgr class
- #>> (fn class => Classparam (c, class));
- fun stmt_fun ((vs, ty), raw_thms) =
- let
- val thms = if null (Term.add_tfreesT ty []) orelse (null o fst o strip_type) ty
- then raw_thms
- else (map o apfst) (Code_Unit.expand_eta thy 1) raw_thms;
- in
- fold_map (translate_tyvar_sort thy algbr funcgr) vs
- ##>> translate_typ thy algbr funcgr ty
- ##>> fold_map (translate_eq thy algbr funcgr) thms
- #>> (fn info => Fun (c, info))
- end;
- val stmt_const = case Code.get_datatype_of_constr thy c
- of SOME tyco => stmt_datatypecons tyco
- | NONE => (case AxClass.class_of_param thy c
- of SOME class => stmt_classparam class
- | NONE => stmt_fun (Code_Wellsorted.typ funcgr c, Code_Wellsorted.eqns funcgr c))
- in ensure_stmt lookup_const (declare_const thy) stmt_const c end
+ ##>> fold_map (translate_typ thy algbr funcgr) tys
+ #>> (fn (tyco, tys) => tyco `%% tys)
and translate_term thy algbr funcgr thm (Const (c, ty)) =
translate_app thy algbr funcgr thm ((c, ty), [])
| translate_term thy algbr funcgr thm (Free (v, _)) =
@@ -617,6 +591,15 @@
translate_term thy algbr funcgr thm t'
##>> fold_map (translate_term thy algbr funcgr thm) ts
#>> (fn (t, ts) => t `$$ ts)
+and translate_eq thy algbr funcgr (thm, proper) =
+ let
+ val (args, rhs) = (apfst (snd o strip_comb) o Logic.dest_equals
+ o Logic.unvarify o prop_of) thm;
+ in
+ fold_map (translate_term thy algbr funcgr (SOME thm)) args
+ ##>> translate_term thy algbr funcgr (SOME thm) rhs
+ #>> rpair (thm, proper)
+ end
and translate_const thy algbr funcgr thm (c, ty) =
let
val tys = Sign.const_typargs thy (c, ty);
@@ -624,9 +607,10 @@
val tys_args = (fst o Term.strip_type) ty;
in
ensure_const thy algbr funcgr c
+ ##>> fold_map (translate_typ thy algbr funcgr) tys
##>> fold_map (translate_dicts thy algbr funcgr thm) (tys ~~ sorts)
##>> fold_map (translate_typ thy algbr funcgr) tys_args
- #>> (fn ((c, iss), tys) => IConst (c, (iss, tys)))
+ #>> (fn (((c, tys), iss), tys_args) => IConst (c, ((tys, iss), tys_args)))
end
and translate_app_const thy algbr funcgr thm (c_ty, ts) =
translate_const thy algbr funcgr thm c_ty
@@ -695,7 +679,38 @@
and translate_app thy algbr funcgr thm (c_ty_ts as ((c, _), _)) =
case Code.get_case_scheme thy c
of SOME case_scheme => translate_app_case thy algbr funcgr thm case_scheme c_ty_ts
- | NONE => translate_app_const thy algbr funcgr thm c_ty_ts;
+ | NONE => translate_app_const thy algbr funcgr thm c_ty_ts
+and translate_tyvar_sort thy (algbr as (proj_sort, _)) funcgr (v, sort) =
+ fold_map (ensure_class thy algbr funcgr) (proj_sort sort)
+ #>> (fn sort => (unprefix "'" v, sort))
+and translate_dicts thy (algbr as (proj_sort, algebra)) funcgr thm (ty, sort) =
+ let
+ val pp = Syntax.pp_global thy;
+ datatype typarg =
+ Global of (class * string) * typarg list list
+ | Local of (class * class) list * (string * (int * sort));
+ fun class_relation (Global ((_, tyco), yss), _) class =
+ Global ((class, tyco), yss)
+ | class_relation (Local (classrels, v), subclass) superclass =
+ Local ((subclass, superclass) :: classrels, v);
+ fun type_constructor tyco yss class =
+ Global ((class, tyco), (map o map) fst yss);
+ fun type_variable (TFree (v, sort)) =
+ let
+ val sort' = proj_sort sort;
+ in map_index (fn (n, class) => (Local ([], (v, (n, sort'))), class)) sort' end;
+ val typargs = Sorts.of_sort_derivation pp algebra
+ {class_relation = class_relation, type_constructor = type_constructor,
+ type_variable = type_variable} (ty, proj_sort sort)
+ handle Sorts.CLASS_ERROR e => not_wellsorted thy thm ty sort e;
+ fun mk_dict (Global (inst, yss)) =
+ ensure_inst thy algbr funcgr inst
+ ##>> (fold_map o fold_map) mk_dict yss
+ #>> (fn (inst, dss) => DictConst (inst, dss))
+ | mk_dict (Local (classrels, (v, (k, sort)))) =
+ fold_map (ensure_classrel thy algbr funcgr) classrels
+ #>> (fn classrels => DictVar (classrels, (unprefix "'" v, (k, length sort))))
+ in fold_map mk_dict typargs end;
(* store *)
@@ -733,14 +748,14 @@
fun generate_consts thy algebra funcgr =
fold_map (ensure_const thy algebra funcgr);
in
- invoke_generation thy (Code_Wellsorted.make thy cs) generate_consts cs
+ invoke_generation thy (Code_Wellsorted.obtain thy cs []) generate_consts cs
|-> project_consts
end;
(* value evaluation *)
-fun ensure_value thy algbr funcgr t =
+fun ensure_value thy algbr funcgr t =
let
val ty = fastype_of t;
val vs = fold_term_types (K (fold_atyps (insert (eq_fst op =)
@@ -753,31 +768,107 @@
(Term.dummy_patternN, ((vs, ty), [(([], t), (Drule.dummy_thm, true))])));
fun term_value (dep, (naming, program1)) =
let
- val Fun (_, ((vs, ty), [(([], t), _)])) =
+ val Fun (_, (vs_ty, [(([], t), _)])) =
Graph.get_node program1 Term.dummy_patternN;
val deps = Graph.imm_succs program1 Term.dummy_patternN;
val program2 = Graph.del_nodes [Term.dummy_patternN] program1;
val deps_all = Graph.all_succs program2 deps;
val program3 = Graph.subgraph (member (op =) deps_all) program2;
- in (((naming, program3), (((vs, ty), t), deps)), (dep, (naming, program2))) end;
+ in (((naming, program3), ((vs_ty, t), deps)), (dep, (naming, program2))) end;
in
ensure_stmt ((K o K) NONE) pair stmt_value Term.dummy_patternN
#> snd
#> term_value
end;
-fun eval thy evaluator t =
+fun base_evaluator thy evaluator algebra funcgr vs t =
let
- val (t', evaluator'') = evaluator t;
- fun evaluator' algebra funcgr =
+ val (((naming, program), (((vs', ty'), t'), deps)), _) =
+ invoke_generation thy (algebra, funcgr) ensure_value t;
+ val vs'' = map (fn (v, _) => (v, (the o AList.lookup (op =) vs o prefix "'") v)) vs';
+ in evaluator naming program ((vs'', (vs', ty')), t') deps end;
+
+fun eval_conv thy prep_sort = Code_Wellsorted.eval_conv thy prep_sort o base_evaluator thy;
+fun eval thy prep_sort postproc = Code_Wellsorted.eval thy prep_sort postproc o base_evaluator thy;
+
+
+(** diagnostic commands **)
+
+fun read_const_exprs thy =
+ let
+ fun consts_of some_thyname =
let
- val (((naming, program), (vs_ty_t, deps)), _) =
- invoke_generation thy (algebra, funcgr) ensure_value t';
- in evaluator'' naming program vs_ty_t deps end;
- in (t', evaluator') end
+ val thy' = case some_thyname
+ of SOME thyname => ThyInfo.the_theory thyname thy
+ | NONE => thy;
+ val cs = Symtab.fold (fn (c, (_, NONE)) => cons c | _ => I)
+ ((snd o #constants o Consts.dest o #consts o Sign.rep_sg) thy') [];
+ fun belongs_here c =
+ not (exists (fn thy'' => Sign.declared_const thy'' c) (Theory.parents_of thy'))
+ in case some_thyname
+ of NONE => cs
+ | SOME thyname => filter belongs_here cs
+ end;
+ fun read_const_expr "*" = ([], consts_of NONE)
+ | read_const_expr s = if String.isSuffix ".*" s
+ then ([], consts_of (SOME (unsuffix ".*" s)))
+ else ([Code_Unit.read_const thy s], []);
+ in pairself flat o split_list o map read_const_expr end;
+
+fun code_depgr thy consts =
+ let
+ val (_, eqngr) = Code_Wellsorted.obtain thy consts [];
+ val select = Graph.all_succs eqngr consts;
+ in
+ eqngr
+ |> not (null consts) ? Graph.subgraph (member (op =) select)
+ |> Graph.map_nodes ((apsnd o map o apfst) (AxClass.overload thy))
+ end;
+
+fun code_thms thy = Pretty.writeln o Code_Wellsorted.pretty thy o code_depgr thy;
-fun eval_conv thy = Code_Wellsorted.eval_conv thy o eval thy;
-fun eval_term thy = Code_Wellsorted.eval_term thy o eval thy;
+fun code_deps thy consts =
+ let
+ val eqngr = code_depgr thy consts;
+ val constss = Graph.strong_conn eqngr;
+ val mapping = Symtab.empty |> fold (fn consts => fold (fn const =>
+ Symtab.update (const, consts)) consts) constss;
+ fun succs consts = consts
+ |> maps (Graph.imm_succs eqngr)
+ |> subtract (op =) consts
+ |> map (the o Symtab.lookup mapping)
+ |> distinct (op =);
+ val conn = [] |> fold (fn consts => cons (consts, succs consts)) constss;
+ fun namify consts = map (Code_Unit.string_of_const thy) consts
+ |> commas;
+ val prgr = map (fn (consts, constss) =>
+ { name = namify consts, ID = namify consts, dir = "", unfold = true,
+ path = "", parents = map namify constss }) conn;
+ in Present.display_graph prgr end;
+
+local
+
+structure P = OuterParse
+and K = OuterKeyword
+
+fun code_thms_cmd thy = code_thms thy o op @ o read_const_exprs thy;
+fun code_deps_cmd thy = code_deps thy o op @ o read_const_exprs thy;
+
+in
+
+val _ =
+ OuterSyntax.improper_command "code_thms" "print system of code equations for code" OuterKeyword.diag
+ (Scan.repeat P.term_group
+ >> (fn cs => Toplevel.no_timing o Toplevel.unknown_theory
+ o Toplevel.keep ((fn thy => code_thms_cmd thy cs) o Toplevel.theory_of)));
+
+val _ =
+ OuterSyntax.improper_command "code_deps" "visualize dependencies of code equations for code" OuterKeyword.diag
+ (Scan.repeat P.term_group
+ >> (fn cs => Toplevel.no_timing o Toplevel.unknown_theory
+ o Toplevel.keep ((fn thy => code_deps_cmd thy cs) o Toplevel.theory_of)));
+
+end;
end; (*struct*)
--- a/src/Tools/code/code_wellsorted.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Tools/code/code_wellsorted.ML Mon May 11 17:20:52 2009 +0200
@@ -7,25 +7,26 @@
signature CODE_WELLSORTED =
sig
- type T
- val eqns: T -> string -> (thm * bool) list
- val typ: T -> string -> (string * sort) list * typ
- val all: T -> string list
- val pretty: theory -> T -> Pretty.T
- val make: theory -> string list
- -> ((sort -> sort) * Sorts.algebra) * T
- val eval_conv: theory
- -> (term -> term * (((sort -> sort) * Sorts.algebra) -> T -> thm)) -> cterm -> thm
- val eval_term: theory
- -> (term -> term * (((sort -> sort) * Sorts.algebra) -> T -> 'a)) -> term -> 'a
+ type code_algebra
+ type code_graph
+ val eqns: code_graph -> string -> (thm * bool) list
+ val typ: code_graph -> string -> (string * sort) list * typ
+ val all: code_graph -> string list
+ val pretty: theory -> code_graph -> Pretty.T
+ val obtain: theory -> string list -> term list -> code_algebra * code_graph
+ val eval_conv: theory -> (sort -> sort)
+ -> (code_algebra -> code_graph -> (string * sort) list -> term -> cterm -> thm) -> cterm -> thm
+ val eval: theory -> (sort -> sort) -> ((term -> term) -> 'a -> 'a)
+ -> (code_algebra -> code_graph -> (string * sort) list -> term -> 'a) -> term -> 'a
end
structure Code_Wellsorted : CODE_WELLSORTED =
struct
-(** the equation graph type **)
+(** the algebra and code equation graph types **)
-type T = (((string * sort) list * typ) * (thm * bool) list) Graph.T;
+type code_algebra = (sort -> sort) * Sorts.algebra;
+type code_graph = (((string * sort) list * typ) * (thm * bool) list) Graph.T;
fun eqns eqngr = these o Option.map snd o try (Graph.get_node eqngr);
fun typ eqngr = fst o Graph.get_node eqngr;
@@ -47,8 +48,10 @@
(* auxiliary *)
+fun is_proper_class thy = can (AxClass.get_info thy);
+
fun complete_proper_sort thy =
- Sign.complete_sort thy #> filter (can (AxClass.get_info thy));
+ Sign.complete_sort thy #> filter (is_proper_class thy);
fun inst_params thy tyco =
map (fn (c, _) => AxClass.param_of_inst thy (c, tyco))
@@ -61,7 +64,7 @@
fun tyscm_rhss_of thy c eqns =
let
val tyscm = case eqns of [] => Code.default_typscheme thy c
- | ((thm, _) :: _) => (snd o Code_Unit.head_eqn thy) thm;
+ | ((thm, _) :: _) => Code_Unit.typscheme_eqn thy thm;
val rhss = consts_of thy eqns;
in (tyscm, rhss) end;
@@ -104,7 +107,7 @@
| NONE => let
val eqns = Code.these_eqns thy c
|> burrow_fst (Code_Unit.norm_args thy)
- |> burrow_fst (Code_Unit.norm_varnames thy Code_Name.purify_tvar Code_Name.purify_var);
+ |> burrow_fst (Code_Unit.norm_varnames thy);
val ((lhs, _), rhss) = tyscm_rhss_of thy c eqns;
in ((lhs, rhss), eqns) end;
@@ -232,8 +235,7 @@
((class, tyco), map (fn k => (snd o Vargraph.get_node vardeps) (Inst (class, tyco), k))
(0 upto Sign.arity_number thy tyco - 1));
-fun add_eqs thy (proj_sort, algebra) vardeps
- (c, (proto_lhs, proto_eqns)) (rhss, eqngr) =
+fun add_eqs thy vardeps (c, (proto_lhs, proto_eqns)) (rhss, eqngr) =
if can (Graph.get_node eqngr) c then (rhss, eqngr)
else let
val lhs = map_index (fn (k, (v, _)) =>
@@ -246,72 +248,30 @@
val eqngr' = Graph.new_node (c, (tyscm, eqns)) eqngr;
in (map (pair c) rhss' @ rhss, eqngr') end;
-fun extend_arities_eqngr thy cs cs_rhss (arities, eqngr) =
+fun extend_arities_eqngr thy cs ts (arities, eqngr) =
let
- val cs_rhss' = (map o apsnd o map) (styp_of NONE) cs_rhss;
+ val cs_rhss = (fold o fold_aterms) (fn Const (c_ty as (c, _)) =>
+ insert (op =) (c, (map (styp_of NONE) o Sign.const_typargs thy) c_ty) | _ => I) ts [];
val (vardeps, (eqntab, insts)) = empty_vardeps_data
|> fold (assert_fun thy arities eqngr) cs
- |> fold (assert_rhs thy arities eqngr) cs_rhss';
+ |> fold (assert_rhs thy arities eqngr) cs_rhss;
val arities' = fold (add_arity thy vardeps) insts arities;
val pp = Syntax.pp_global thy;
- val is_proper_class = can (AxClass.get_info thy);
- val (proj_sort, algebra) = Sorts.subalgebra pp is_proper_class
+ val algebra = Sorts.subalgebra pp (is_proper_class thy)
(AList.lookup (op =) arities') (Sign.classes_of thy);
- val (rhss, eqngr') = Symtab.fold
- (add_eqs thy (proj_sort, algebra) vardeps) eqntab ([], eqngr);
- fun deps_of (c, rhs) = c ::
- maps (dicts_of thy (proj_sort, algebra))
- (rhs ~~ (map snd o fst o fst o Graph.get_node eqngr') c);
+ val (rhss, eqngr') = Symtab.fold (add_eqs thy vardeps) eqntab ([], eqngr);
+ fun deps_of (c, rhs) = c :: maps (dicts_of thy algebra)
+ (rhs ~~ (map snd o fst o fst o Graph.get_node eqngr') c);
val eqngr'' = fold (fn (c, rhs) => fold
(curry Graph.add_edge c) (deps_of rhs)) rhss eqngr';
- in ((proj_sort, algebra), (arities', eqngr'')) end;
+ in (algebra, (arities', eqngr'')) end;
-(** retrieval interfaces **)
-
-fun proto_eval thy cterm_of evaluator_lift evaluator proto_ct arities_eqngr =
- let
- val ct = cterm_of proto_ct;
- val _ = Sign.no_vars (Syntax.pp_global thy) (Thm.term_of ct);
- val _ = Term.fold_types (Type.no_tvars #> K I) (Thm.term_of ct) ();
- fun consts_of t =
- fold_aterms (fn Const c_ty => cons c_ty | _ => I) t [];
- val thm = Code.preprocess_conv thy ct;
- val ct' = Thm.rhs_of thm;
- val t' = Thm.term_of ct';
- val (t'', evaluator_eqngr) = evaluator t';
- val consts = map fst (consts_of t');
- val consts' = consts_of t'';
- val const_matches' = fold (fn (c, ty) =>
- insert (op =) (c, Sign.const_typargs thy (c, ty))) consts' [];
- val (algebra', arities_eqngr') =
- extend_arities_eqngr thy consts const_matches' arities_eqngr;
- in
- (evaluator_lift (evaluator_eqngr algebra') thm (snd arities_eqngr'),
- arities_eqngr')
- end;
-
-fun proto_eval_conv thy =
- let
- fun evaluator_lift evaluator thm1 eqngr =
- let
- val thm2 = evaluator eqngr;
- val thm3 = Code.postprocess_conv thy (Thm.rhs_of thm2);
- in
- Thm.transitive thm1 (Thm.transitive thm2 thm3) handle THM _ =>
- error ("could not construct evaluation proof:\n"
- ^ (cat_lines o map Display.string_of_thm) [thm1, thm2, thm3])
- end;
- in proto_eval thy I evaluator_lift end;
-
-fun proto_eval_term thy =
- let
- fun evaluator_lift evaluator _ eqngr = evaluator eqngr;
- in proto_eval thy (Thm.cterm_of thy) evaluator_lift end;
+(** store **)
structure Wellsorted = CodeDataFun
(
- type T = ((string * class) * sort list) list * T;
+ type T = ((string * class) * sort list) list * code_graph;
val empty = ([], Graph.empty);
fun purge thy cs (arities, eqngr) =
let
@@ -327,71 +287,56 @@
in (arities', eqngr') end;
);
-fun make thy cs = apsnd snd
- (Wellsorted.change_yield thy (extend_arities_eqngr thy cs []));
-fun eval_conv thy f =
- fst o Wellsorted.change_yield thy o proto_eval_conv thy f;
+(** retrieval interfaces **)
-fun eval_term thy f =
- fst o Wellsorted.change_yield thy o proto_eval_term thy f;
+fun obtain thy cs ts = apsnd snd
+ (Wellsorted.change_yield thy (extend_arities_eqngr thy cs ts));
-
-(** diagnostic commands **)
+fun prepare_sorts_typ prep_sort
+ = map_type_tfree (fn (v, sort) => TFree (v, prep_sort sort));
-fun code_depgr thy consts =
- let
- val (_, eqngr) = make thy consts;
- val select = Graph.all_succs eqngr consts;
- in
- eqngr
- |> not (null consts) ? Graph.subgraph (member (op =) select)
- |> Graph.map_nodes ((apsnd o map o apfst) (AxClass.overload thy))
- end;
+fun prepare_sorts prep_sort (Const (c, ty)) =
+ Const (c, prepare_sorts_typ prep_sort ty)
+ | prepare_sorts prep_sort (t1 $ t2) =
+ prepare_sorts prep_sort t1 $ prepare_sorts prep_sort t2
+ | prepare_sorts prep_sort (Abs (v, ty, t)) =
+ Abs (v, prepare_sorts_typ prep_sort ty, prepare_sorts prep_sort t)
+ | prepare_sorts _ (t as Bound _) = t;
-fun code_thms thy = Pretty.writeln o pretty thy o code_depgr thy;
-
-fun code_deps thy consts =
+fun gen_eval thy cterm_of conclude_evaluation prep_sort evaluator proto_ct =
let
- val eqngr = code_depgr thy consts;
- val constss = Graph.strong_conn eqngr;
- val mapping = Symtab.empty |> fold (fn consts => fold (fn const =>
- Symtab.update (const, consts)) consts) constss;
- fun succs consts = consts
- |> maps (Graph.imm_succs eqngr)
- |> subtract (op =) consts
- |> map (the o Symtab.lookup mapping)
- |> distinct (op =);
- val conn = [] |> fold (fn consts => cons (consts, succs consts)) constss;
- fun namify consts = map (Code_Unit.string_of_const thy) consts
- |> commas;
- val prgr = map (fn (consts, constss) =>
- { name = namify consts, ID = namify consts, dir = "", unfold = true,
- path = "", parents = map namify constss }) conn;
- in Present.display_graph prgr end;
-
-local
+ val pp = Syntax.pp_global thy;
+ val ct = cterm_of proto_ct;
+ val _ = (Sign.no_frees pp o map_types (K dummyT) o Sign.no_vars pp)
+ (Thm.term_of ct);
+ val thm = Code.preprocess_conv thy ct;
+ val ct' = Thm.rhs_of thm;
+ val t' = Thm.term_of ct';
+ val vs = Term.add_tfrees t' [];
+ val consts = fold_aterms
+ (fn Const (c, _) => insert (op =) c | _ => I) t' [];
+
+ val t'' = prepare_sorts prep_sort t';
+ val (algebra', eqngr') = obtain thy consts [t''];
+ in conclude_evaluation (evaluator algebra' eqngr' vs t'' ct') thm end;
-structure P = OuterParse
-and K = OuterKeyword
-
-fun code_thms_cmd thy = code_thms thy o op @ o Code_Name.read_const_exprs thy;
-fun code_deps_cmd thy = code_deps thy o op @ o Code_Name.read_const_exprs thy;
-
-in
+fun simple_evaluator evaluator algebra eqngr vs t ct =
+ evaluator algebra eqngr vs t;
-val _ =
- OuterSyntax.improper_command "code_thms" "print system of code equations for code" OuterKeyword.diag
- (Scan.repeat P.term_group
- >> (fn cs => Toplevel.no_timing o Toplevel.unknown_theory
- o Toplevel.keep ((fn thy => code_thms_cmd thy cs) o Toplevel.theory_of)));
+fun eval_conv thy =
+ let
+ fun conclude_evaluation thm2 thm1 =
+ let
+ val thm3 = Code.postprocess_conv thy (Thm.rhs_of thm2);
+ in
+ Thm.transitive thm1 (Thm.transitive thm2 thm3) handle THM _ =>
+ error ("could not construct evaluation proof:\n"
+ ^ (cat_lines o map Display.string_of_thm) [thm1, thm2, thm3])
+ end;
+ in gen_eval thy I conclude_evaluation end;
-val _ =
- OuterSyntax.improper_command "code_deps" "visualize dependencies of code equations for code" OuterKeyword.diag
- (Scan.repeat P.term_group
- >> (fn cs => Toplevel.no_timing o Toplevel.unknown_theory
- o Toplevel.keep ((fn thy => code_deps_cmd thy cs) o Toplevel.theory_of)));
-
-end;
+fun eval thy prep_sort postproc evaluator = gen_eval thy (Thm.cterm_of thy)
+ (K o postproc (Code.postprocess_term thy)) prep_sort (simple_evaluator evaluator);
end; (*struct*)
--- a/src/Tools/nbe.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Tools/nbe.ML Mon May 11 17:20:52 2009 +0200
@@ -7,11 +7,10 @@
signature NBE =
sig
val norm_conv: cterm -> thm
- val norm_term: theory -> term -> term
+ val norm: theory -> term -> term
datatype Univ =
Const of int * Univ list (*named (uninterpreted) constants*)
- | Free of string * Univ list (*free (uninterpreted) variables*)
| DFree of string * int (*free (uninterpreted) dictionary parameters*)
| BVar of int * Univ list
| Abs of (int * (Univ list -> Univ)) * Univ list
@@ -57,14 +56,12 @@
datatype Univ =
Const of int * Univ list (*named (uninterpreted) constants*)
- | Free of string * Univ list (*free variables*)
| DFree of string * int (*free (uninterpreted) dictionary parameters*)
| BVar of int * Univ list (*bound variables, named*)
| Abs of (int * (Univ list -> Univ)) * Univ list
(*abstractions as closures*);
fun same (Const (k, xs)) (Const (l, ys)) = k = l andalso sames xs ys
- | same (Free (s, xs)) (Free (t, ys)) = s = t andalso sames xs ys
| same (DFree (s, k)) (DFree (t, l)) = s = t andalso k = l
| same (BVar (k, xs)) (BVar (l, ys)) = k = l andalso sames xs ys
| same _ _ = false
@@ -80,7 +77,6 @@
| GREATER => Abs ((k, f), ys @ xs) (*note: reverse convention also for apps!*)
end
| apps (Const (name, xs)) ys = Const (name, ys @ xs)
- | apps (Free (name, xs)) ys = Free (name, ys @ xs)
| apps (BVar (n, xs)) ys = BVar (n, ys @ xs);
@@ -194,7 +190,7 @@
let
val (t', ts) = Code_Thingol.unfold_app t
in of_iapp match_cont t' (fold_rev (cons o of_iterm NONE) ts []) end
- and of_iapp match_cont (IConst (c, (dss, _))) ts = constapp c dss ts
+ and of_iapp match_cont (IConst (c, ((_, dss), _))) ts = constapp c dss ts
| of_iapp match_cont (IVar v) ts = nbe_apps (nbe_bound v) ts
| of_iapp match_cont ((v, _) `|-> t) ts =
nbe_apps (nbe_abss 1 (ml_abs (ml_list [nbe_bound v]) (of_iterm NONE t))) ts
@@ -299,15 +295,15 @@
val params = Name.invent_list [] "d" (length names);
fun mk (k, name) =
(name, ([(v, [])],
- [([IConst (class, ([], [])) `$$ map IVar params], IVar (nth params k))]));
+ [([IConst (class, (([], []), [])) `$$ map IVar params], IVar (nth params k))]));
in map_index mk names end
| eqns_of_stmt (_, Code_Thingol.Classrel _) =
[]
| eqns_of_stmt (_, Code_Thingol.Classparam _) =
[]
| eqns_of_stmt (inst, Code_Thingol.Classinst ((class, (_, arities)), (superinsts, instops))) =
- [(inst, (arities, [([], IConst (class, ([], [])) `$$
- map (fn (_, (_, (inst, dicts))) => IConst (inst, (dicts, []))) superinsts
+ [(inst, (arities, [([], IConst (class, (([], []), [])) `$$
+ map (fn (_, (_, (inst, dicts))) => IConst (inst, (([], dicts), []))) superinsts
@ map (IConst o snd o fst) instops)]))];
fun compile_stmts ctxt stmts_deps =
@@ -350,20 +346,27 @@
(* term evaluation *)
-fun eval_term ctxt gr deps ((vs, ty) : typscheme, t) =
+fun eval_term ctxt gr deps (vs : (string * sort) list, t) =
let
- val frees = Code_Thingol.fold_unbound_varnames (insert (op =)) t []
- val frees' = map (fn v => Free (v, [])) frees;
val dict_frees = maps (fn (v, sort) => map_index (curry DFree v o fst) sort) vs;
in
- ("", (vs, [(map IVar frees, t)]))
+ ("", (vs, [([], t)]))
|> singleton (compile_eqnss ctxt gr deps)
|> snd
- |> (fn t => apps t (rev (dict_frees @ frees')))
+ |> (fn t => apps t (rev dict_frees))
end;
(* reification *)
+fun typ_of_itype program vs (ityco `%% itys) =
+ let
+ val Code_Thingol.Datatype (tyco, _) = Graph.get_node program ityco;
+ in Type (tyco, map (typ_of_itype program vs) itys) end
+ | typ_of_itype program vs (ITyVar v) =
+ let
+ val sort = (the o AList.lookup (op =) vs) v;
+ in TFree ("'" ^ v, sort) end;
+
fun term_of_univ thy program idx_tab t =
let
fun take_until f [] = []
@@ -390,8 +393,6 @@
val T' = map_type_tfree (fn (v, _) => TypeInfer.param typidx (v, [])) T;
val typidx' = typidx + 1;
in of_apps bounds (Term.Const (c, T'), ts') typidx' end
- | of_univ bounds (Free (name, ts)) typidx =
- of_apps bounds (Term.Free (name, dummyT), ts) typidx
| of_univ bounds (BVar (n, ts)) typidx =
of_apps bounds (Bound (bounds - n - 1), ts) typidx
| of_univ bounds (t as Abs _) typidx =
@@ -418,43 +419,37 @@
(* compilation, evaluation and reification *)
-fun compile_eval thy naming program vs_ty_t deps =
+fun compile_eval thy naming program vs_t deps =
let
val ctxt = ProofContext.init thy;
val (_, (gr, (_, idx_tab))) =
Nbe_Functions.change thy (ensure_stmts ctxt naming program o snd);
in
- vs_ty_t
+ vs_t
|> eval_term ctxt gr deps
|> term_of_univ thy program idx_tab
end;
(* evaluation with type reconstruction *)
-fun eval thy t naming program vs_ty_t deps =
+fun normalize thy naming program ((vs0, (vs, ty)), t) deps =
let
fun subst_const f = map_aterms (fn t as Term.Const (c, ty) => Term.Const (f c, ty)
| t => t);
- val subst_triv_consts = subst_const (Code_Unit.resubst_alias thy);
- val ty = type_of t;
- val type_free = AList.lookup (op =)
- (map (fn (s, T) => (s, Term.Free (s, T))) (Term.add_frees t []));
- val type_frees = Term.map_aterms
- (fn (t as Term.Free (s, _)) => the_default t (type_free s) | t => t);
+ val resubst_triv_consts = subst_const (Code_Unit.resubst_alias thy);
+ val ty' = typ_of_itype program vs0 ty;
fun type_infer t =
singleton (TypeInfer.infer_types (Syntax.pp_global thy) (Sign.tsig_of thy) I
(try (Type.strip_sorts o Sign.the_const_type thy)) (K NONE) Name.context 0)
- (TypeInfer.constrain ty t);
+ (TypeInfer.constrain ty' t);
fun check_tvars t = if null (Term.add_tvars t []) then t else
error ("Illegal schematic type variables in normalized term: "
^ setmp show_types true (Syntax.string_of_term_global thy) t);
val string_of_term = setmp show_types true (Syntax.string_of_term_global thy);
in
- compile_eval thy naming program vs_ty_t deps
+ compile_eval thy naming program (vs, t) deps
|> tracing (fn t => "Normalized:\n" ^ string_of_term t)
- |> subst_triv_consts
- |> type_frees
- |> tracing (fn t => "Vars typed:\n" ^ string_of_term t)
+ |> resubst_triv_consts
|> type_infer
|> tracing (fn t => "Types inferred:\n" ^ string_of_term t)
|> check_tvars
@@ -463,39 +458,59 @@
(* evaluation oracle *)
-val (_, norm_oracle) = Context.>>> (Context.map_theory_result
- (Thm.add_oracle (Binding.name "norm", fn (thy, t, naming, program, vs_ty_t, deps) =>
- Thm.cterm_of thy (Logic.mk_equals (t, eval thy t naming program vs_ty_t deps)))));
+fun add_triv_classes thy = curry (Sorts.inter_sort (Sign.classes_of thy))
+ (Code_Unit.triv_classes thy);
-fun add_triv_classes thy =
+fun mk_equals thy lhs raw_rhs =
+ let
+ val ty = Thm.typ_of (Thm.ctyp_of_term lhs);
+ val eq = Thm.cterm_of thy (Term.Const ("==", ty --> ty --> propT));
+ val rhs = Thm.cterm_of thy raw_rhs;
+ in Thm.mk_binop eq lhs rhs end;
+
+val (_, raw_norm_oracle) = Context.>>> (Context.map_theory_result
+ (Thm.add_oracle (Binding.name "norm", fn (thy, naming, program, vsp_ty_t, deps, ct) =>
+ mk_equals thy ct (normalize thy naming program vsp_ty_t deps))));
+
+fun norm_oracle thy naming program vsp_ty_t deps ct =
+ raw_norm_oracle (thy, naming, program, vsp_ty_t, deps, ct);
+
+fun no_frees_conv conv ct =
let
- val inters = curry (Sorts.inter_sort (Sign.classes_of thy))
- (Code_Unit.triv_classes thy);
- fun map_sorts f = (map_types o map_atyps)
- (fn TVar (v, sort) => TVar (v, f sort)
- | TFree (v, sort) => TFree (v, f sort));
- in map_sorts inters end;
+ val frees = Thm.add_cterm_frees ct [];
+ fun apply_beta free thm = Thm.combination thm (Thm.reflexive free)
+ |> Conv.fconv_rule (Conv.arg_conv (Conv.try_conv (Thm.beta_conversion false)))
+ |> Conv.fconv_rule (Conv.arg1_conv (Thm.beta_conversion false));
+ in
+ ct
+ |> fold_rev Thm.cabs frees
+ |> conv
+ |> fold apply_beta frees
+ end;
-fun norm_conv ct =
+fun no_frees_rew rew t =
+ let
+ val frees = map Free (Term.add_frees t []);
+ in
+ t
+ |> fold_rev lambda frees
+ |> rew
+ |> (fn t' => Term.betapplys (t', frees))
+ end;
+
+val norm_conv = no_frees_conv (fn ct =>
let
val thy = Thm.theory_of_cterm ct;
- fun evaluator' t naming program vs_ty_t deps =
- norm_oracle (thy, t, naming, program, vs_ty_t, deps);
- fun evaluator t = (add_triv_classes thy t, evaluator' t);
- in Code_Thingol.eval_conv thy evaluator ct end;
+ in Code_Thingol.eval_conv thy (add_triv_classes thy) (norm_oracle thy) ct end);
-fun norm_term thy t =
- let
- fun evaluator' t naming program vs_ty_t deps = eval thy t naming program vs_ty_t deps;
- fun evaluator t = (add_triv_classes thy t, evaluator' t);
- in (Code.postprocess_term thy o Code_Thingol.eval_term thy evaluator) t end;
+fun norm thy = no_frees_rew (Code_Thingol.eval thy (add_triv_classes thy) I (normalize thy));
(* evaluation command *)
fun norm_print_term ctxt modes t =
let
val thy = ProofContext.theory_of ctxt;
- val t' = norm_term thy t;
+ val t' = norm thy t;
val ty' = Term.type_of t';
val ctxt' = Variable.auto_fixes t ctxt;
val p = PrintMode.with_modes modes (fn () =>
@@ -510,8 +525,7 @@
let val ctxt = Toplevel.context_of state
in norm_print_term ctxt modes (Syntax.read_term ctxt s) end;
-val setup =
- Value.add_evaluator ("nbe", norm_term o ProofContext.theory_of);
+val setup = Value.add_evaluator ("nbe", norm o ProofContext.theory_of);
local structure P = OuterParse and K = OuterKeyword in
--- a/src/Tools/quickcheck.ML Mon May 11 09:39:53 2009 +0200
+++ b/src/Tools/quickcheck.ML Mon May 11 17:20:52 2009 +0200
@@ -6,28 +6,48 @@
signature QUICKCHECK =
sig
- val test_term: Proof.context -> bool -> string option -> int -> int -> term -> (string * term) list option;
- val add_generator: string * (Proof.context -> term -> int -> term list option) -> theory -> theory
val auto: bool ref
val auto_time_limit: int ref
+ val test_term: Proof.context -> bool -> string option -> int -> int -> term ->
+ (string * term) list option
+ val add_generator: string * (Proof.context -> term -> int -> term list option) -> theory -> theory
end;
structure Quickcheck : QUICKCHECK =
struct
+(* preferences *)
+
+val auto = ref false;
+val auto_time_limit = ref 2500;
+
+val _ =
+ ProofGeneralPgip.add_preference Preferences.category_tracing
+ (setmp auto true (fn () =>
+ Preferences.bool_pref auto
+ "auto-quickcheck"
+ "Whether to enable quickcheck automatically.") ());
+
+val _ =
+ ProofGeneralPgip.add_preference Preferences.category_tracing
+ (Preferences.nat_pref auto_time_limit
+ "auto-quickcheck-time-limit"
+ "Time limit for automatic quickcheck (in milliseconds).");
+
+
(* quickcheck configuration -- default parameters, test generators *)
datatype test_params = Test_Params of
{ size: int, iterations: int, default_type: typ option };
-fun dest_test_params (Test_Params { size, iterations, default_type}) =
+fun dest_test_params (Test_Params { size, iterations, default_type }) =
((size, iterations), default_type);
fun mk_test_params ((size, iterations), default_type) =
Test_Params { size = size, iterations = iterations, default_type = default_type };
fun map_test_params f (Test_Params { size, iterations, default_type}) =
mk_test_params (f ((size, iterations), default_type));
-fun merge_test_params (Test_Params {size = size1, iterations = iterations1, default_type = default_type1},
- Test_Params {size = size2, iterations = iterations2, default_type = default_type2}) =
+fun merge_test_params (Test_Params { size = size1, iterations = iterations1, default_type = default_type1 },
+ Test_Params { size = size2, iterations = iterations2, default_type = default_type2 }) =
mk_test_params ((Int.max (size1, size2), Int.max (iterations1, iterations2)),
case default_type1 of NONE => default_type2 | _ => default_type1);
@@ -138,10 +158,7 @@
(* automatic testing *)
-val auto = ref false;
-val auto_time_limit = ref 5000;
-
-fun test_goal_auto int state =
+val _ = Context.>> (Specification.add_theorem_hook (fn int => fn state =>
let
val ctxt = Proof.context_of state;
val assms = map term_of (Assumption.all_assms_of ctxt);
@@ -162,12 +179,10 @@
if int andalso !auto andalso not (!Toplevel.quiet)
then test ()
else state
- end;
-
-val _ = Context.>> (Specification.add_theorem_hook test_goal_auto);
+ end));
-(* Isar interfaces *)
+(* Isar commands *)
fun read_nat s = case (Library.read_int o Symbol.explode) s
of (k, []) => if k >= 0 then k