# HG changeset patch # User haftmann # Date 1242055252 -7200 # Node ID 0ce5f53fc65d56cc3f747cbfb9002cb3a38c6b9c # Parent 657386d94f14efd61203cf6fde21071e07aa8830# Parent ee45b1c733c16b08c779d89afbcdad2ccdf808c1 merged diff -r 657386d94f14 -r 0ce5f53fc65d Admin/mirror-website --- 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}" diff -r 657386d94f14 -r 0ce5f53fc65d CONTRIBUTORS --- 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. diff -r 657386d94f14 -r 0ce5f53fc65d NEWS --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d contrib/SystemOnTPTP/remote --- 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 [] \n"); - print(" are ...\n"); - print(" -h - print this help\n"); - print(" -w - list available ATP systems\n"); - print(" -s - specified system to use\n"); - print(" -t - CPU time limit for system\n"); - print(" -c - custom command for system\n"); - print(" - 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); -} - diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Makefile --- 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=$@ $< diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/Adaptation.thy --- /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", 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\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 \ nat \ nat \ bool" where + "in_interval (k, l) n \ k \ n \ n \ l" +(*<*) +code_type %invisible bool + (SML) +code_const %invisible True and False and "op \" 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 \" + (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 \" + (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 "\" 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\bar) y \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/Adaption.thy --- 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", 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\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 \ nat \ nat \ bool" where - "in_interval (k, l) n \ k \ n \ n \ l" -(*<*) -code_type %invisible bool - (SML) -code_const %invisible True and False and "op \" 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 \" - (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 \" - (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 "\" 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\bar) y \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/Further.thy --- 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/Introduction.thy --- 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}). diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/Program.thy --- 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 \ y \ fst x < fst y \ fst x = fst y \ snd x \ snd y" - -definition %quote [code del]: - "x < y \ fst x < fst y \ fst x = fst y \ 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 \ 'a\order, y1 \ 'b\order) < (x2, y2) \ - x1 < x2 \ x1 = x2 \ y1 < y2" - "(x1 \ 'a\order, y1 \ 'b\order) \ (x2, y2) \ - x1 < x2 \ x1 = x2 \ y1 \ 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 \"} 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 \ 'a\{order, eq}, y1 \ 'b\order) < (x2, y2) \ - x1 < x2 \ x1 = x2 \ y1 < y2" - "(x1 \ 'a\{order, eq}, y1 \ 'b\order) \ (x2, y2) \ - x1 < x2 \ x1 = x2 \ y1 \ y2" - by (simp_all add: less_prod_def less_eq_prod_def) - -text {* - \noindent Then code generation succeeds: -*} - -text %quote {*@{code_stmts "op \ \ _ \ _ \ _ \ _ \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/ROOT.ML --- 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"; diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/document/Adaptation.tex --- /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: diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/document/Adaption.tex --- 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: diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/document/Further.tex --- 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% % diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/document/Introduction.tex --- 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}\\ diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/document/Program.tex --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/examples/Example.hs --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/pictures/adaptation.tex --- /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} diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/Thy/pictures/adaption.tex --- 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} diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Codegen/codegen.tex --- 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} diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/IsarRef/Thy/Spec.thy --- 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 :: \ decl"} may be + defined separately on type instances + @{text "c :: (\\<^sub>1, \, \\<^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 :: \ - decl"} may be defined separately on type instances @{text "c :: - (\\<^sub>1, \, \\<^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 "\\<^sub>1, \, \\<^sub>n"}. Incomplete specification patterns impose global constraints on all occurrences, diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/IsarRef/Thy/document/Spec.tex --- 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, diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Main/Docs/Main_Doc.thy --- 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\('a*'a)set"}\\ @{const Transitive_Closure.trancl} & @{term_type_only Transitive_Closure.trancl "('a*'a)set\('a*'a)set"}\\ @{const Transitive_Closure.reflcl} & @{term_type_only Transitive_Closure.reflcl "('a*'a)set\('a*'a)set"}\\ +@{const compower} & @{term_type_only "op ^^ :: ('a*'a)set\nat\('a*'a)set" "('a*'a)set\nat\('a*'a)set"}\\ \end{tabular} \subsubsection*{Syntax} @@ -318,7 +319,6 @@ @{term "op + :: nat \ nat \ nat"} & @{term "op - :: nat \ nat \ nat"} & @{term "op * :: nat \ nat \ nat"} & -@{term "op ^ :: nat \ nat \ nat"} & @{term "op div :: nat \ nat \ nat"}& @{term "op mod :: nat \ nat \ nat"}& @{term "op dvd :: nat \ nat \ 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 \ 'a) \ nat \ 'a \ 'a"} & + @{term_type_only "op ^^ :: ('a \ 'a) \ nat \ 'a \ 'a" "('a \ 'a) \ nat \ 'a \ '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\'a) ^ n"} \ -and relations \ @{term[source]"(r::('a\'a)set) ^ n"}. - - \section{Option} @{datatype option} diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/Main/Docs/document/Main_Doc.tex --- 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} diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/TutorialI/tutorial.tex --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d doc-src/more_antiquote.ML --- 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) diff -r 657386d94f14 -r 0ce5f53fc65d etc/isar-keywords.el --- 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" diff -r 657386d94f14 -r 0ce5f53fc65d lib/jedit/isabelle.xml --- 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 @@ + attach attribute_setup automaton diff -r 657386d94f14 -r 0ce5f53fc65d lib/scripts/SystemOnTPTP --- /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 [] \n"); + print(" are ...\n"); + print(" -h - print this help\n"); + print(" -w - list available ATP systems\n"); + print(" -s - specified system to use\n"); + print(" -t - CPU time limit for system\n"); + print(" -c - custom command for system\n"); + print(" - 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); +} + diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ATP_Linkup.thy --- 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Algebra/abstract/Ring2.thy --- 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 \ 'a \ bool" (infixl "assoc" 50) where diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Algebra/poly/LongDiv.thy --- 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 {* diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Algebra/poly/UnivPoly2.thy --- 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 \ 'a up) ^ 0 = 1" - | "(a \ '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 "\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 *) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Bali/Trans.thy --- 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 \ state,nat,term \ state] \ bool" ("_\_ \_ _"[61,82,82] 81) - where "G\p \n p' \ (p,p') \ {(x, y). step G x y}^n" + where "G\p \n p' \ (p,p') \ {(x, y). step G x y}^^n" abbreviation steptr:: "[prog,term \ state,term \ state] \ bool" ("_\_ \* _"[61,82,82] 81) @@ -370,25 +370,6 @@ Smallstep zu Bigstep, nur wenn nicht die Ausdrücke Callee, FinA ,\ *) -lemma rtrancl_imp_rel_pow: "p \ R^* \ \n. p \ R^n" -proof - - assume "p \ R\<^sup>*" - moreover obtain x y where p: "p = (x,y)" by (cases p) - ultimately have "(x,y) \ R\<^sup>*" by hypsubst - hence "\n. (x,y) \ R^n" - proof induct - fix a have "(a,a) \ R^0" by simp - thus "\n. (a,a) \ R ^ n" .. - next - fix a b c assume "\n. (a,b) \ R ^ n" - then obtain n where "(a,b) \ R^n" .. - moreover assume "(b,c) \ R" - ultimately have "(a,c) \ R^(Suc n)" by auto - thus "\n. (a,c) \ R^n" .. - qed - with p show ?thesis by hypsubst -qed - (* lemma imp_eval_trans: assumes eval: "G\s0 \t\\ (v,s1)" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Code_Eval.thy --- 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::{} \ term" + fixes term_of :: "'a \ term" lemma term_of_anything: "term_of x \ 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 \ message_string \ 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; *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Code_Message.thy --- 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\message_string) = 0" - by (cases s) simp_all - -lemma [code]: "message_string_size (s\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 \ message_string \ message_string \ bool" - (SML "!((_ : string) = _)") - (OCaml "!((_ : string) = _)") - (Haskell infixl 4 "==") - -end diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Code_Setup.thy --- 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\{})" - -code_datatype Trueprop "prop" - -text {* Code equations *} - -lemma [code]: - shows "(True \ PROP P) \ PROP P" - and "(False \ Q) \ Trueprop True" - and "(PROP P \ True) \ Trueprop True" - and "(Q \ False) \ Trueprop (\ Q)" by (auto intro!: equal_intr_rule) - -lemma [code]: - shows "False \ x \ False" - and "True \ x \ x" - and "x \ False \ False" - and "x \ True \ x" by simp_all - -lemma [code]: - shows "False \ x \ x" - and "True \ x \ True" - and "x \ False \ x" - and "x \ True \ True" by simp_all - -lemma [code]: - shows "\ True \ False" - and "\ False \ 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 = \ 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 \ (\x. Let x f)" - shows "CASE x \ f x" - using assms by simp_all - -lemma If_case_cert: - assumes "CASE \ (\b. If b f g)" - shows "(CASE True \ f) &&& (CASE False \ 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 \ \ prop \ prop \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Complex.thy --- 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\complex)" -| "z ^ Suc n = (z\complex) * z ^ n" - -instance proof -qed simp_all - -declare power_complex.simps [simp del] - -end - - subsection {* Numerals and Arithmetic *} instantiation complex :: number_ring diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Decision_Procs/Approximation.thy --- 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 \ nat" and G :: "nat \ nat \ nat" and F :: "nat \ nat" - assumes f_Suc: "\n. f (Suc n) = G ((F^n) s) (f n)" - shows "horner F G n ((F^j') s) (f j') x = (\ j = 0..< n. -1^j * (1 / real (f (j' + j))) * x^j)" + assumes f_Suc: "\n. f (Suc n) = G ((F ^^ n) s) (f n)" + shows "horner F G n ((F ^^ j') s) (f j') x = (\ 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 \ Ifloat x" and f_Suc: "\n. f (Suc n) = G ((F^n) s) (f n)" + assumes "0 \ Ifloat x" and f_Suc: "\n. f (Suc n) = G ((F ^^ n) s) (f n)" and lb_0: "\ i k x. lb 0 i k x = 0" and lb_Suc: "\ 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: "\ i k x. ub 0 i k x = 0" and ub_Suc: "\ 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) \ horner F G n ((F^j') s) (f j') (Ifloat x) \ - horner F G n ((F^j') s) (f j') (Ifloat x) \ Ifloat (ub n ((F^j') s) (f j') x)" + shows "Ifloat (lb n ((F ^^ j') s) (f j') x) \ horner F G n ((F ^^ j') s) (f j') (Ifloat x) \ + horner F G n ((F ^^ j') s) (f j') (Ifloat x) \ Ifloat (ub n ((F ^^ j') s) (f j') x)" (is "?lb n j' \ ?horner n j' \ ?horner n j' \ ?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'))) \ 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 \ Ifloat x` - show "- Ifloat (x * ub n (F ((F ^ j') s)) (G ((F ^ j') s) (f j')) x) \ - (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) \ - (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' \ ?ub (Suc n) j'" unfolding ub_Suc ub_Suc horner.simps Ifloat_sub diff_def proof (rule add_mono) show "1 / real (f j') \ 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 \ Ifloat x` - show "- (Ifloat x * horner F G n (F ((F ^ j') s)) (G ((F ^ j') s) (f j')) (Ifloat x)) \ - - 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)) \ + - 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 \ nat" and G :: "nat \ nat \ nat" - assumes "0 \ Ifloat x" and f_Suc: "\n. f (Suc n) = G ((F^n) s) (f n)" + assumes "0 \ Ifloat x" and f_Suc: "\n. f (Suc n) = G ((F ^^ n) s) (f n)" and lb_0: "\ i k x. lb 0 i k x = 0" and lb_Suc: "\ 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: "\ i k x. ub 0 i k x = 0" and ub_Suc: "\ 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) \ (\j=0..j=0.. Ifloat (ub n ((F^j') s) (f j') x)" (is "?ub") + shows "Ifloat (lb n ((F ^^ j') s) (f j') x) \ (\j=0..j=0.. Ifloat (ub n ((F ^^ j') s) (f j') x)" (is "?ub") proof - have "?lb \ ?ub" using horner_bounds'[where lb=lb, OF `0 \ Ifloat x` f_Suc lb_0 lb_Suc ub_0 ub_Suc] @@ -88,29 +88,29 @@ qed lemma horner_bounds_nonpos: fixes F :: "nat \ nat" and G :: "nat \ nat \ nat" - assumes "Ifloat x \ 0" and f_Suc: "\n. f (Suc n) = G ((F^n) s) (f n)" + assumes "Ifloat x \ 0" and f_Suc: "\n. f (Suc n) = G ((F ^^ n) s) (f n)" and lb_0: "\ i k x. lb 0 i k x = 0" and lb_Suc: "\ 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: "\ i k x. ub 0 i k x = 0" and ub_Suc: "\ 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) \ (\j=0..j=0.. Ifloat (ub n ((F^j') s) (f j') x)" (is "?ub") + shows "Ifloat (lb n ((F ^^ j') s) (f j') x) \ (\j=0..j=0.. 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: "(\j=0..j=0..j = 0.. {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 \ {Ifloat l .. Ifloat u}" - shows "x^n \ {Ifloat l1..Ifloat u1}" + shows "x ^ n \ {Ifloat l1..Ifloat u1}" proof (cases "even n") case True show ?thesis proof (cases "0 < l") case True hence "odd n \ 0 < l" and "0 \ 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 \ 0 < l`] by auto - have "Ifloat l^n \ x^n" and "x^n \ Ifloat u^n " using `0 \ 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 \ x ^ n" and "x ^ n \ Ifloat u ^ n " using `0 \ 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: "\ (odd n \ 0 < l)" using `even n` by auto show ?thesis proof (cases "u < 0") case True hence "0 \ - Ifloat u" and "- Ifloat u \ - x" and "0 \ - x" and "-x \ - Ifloat l" using assms unfolding less_float_def by auto - hence "Ifloat u^n \ x^n" and "x^n \ Ifloat l^n" using power_mono[of "-x" "-Ifloat l" n] power_mono[of "-Ifloat u" "-x" n] + hence "Ifloat u ^ n \ x ^ n" and "x ^ n \ 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 \ 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 \ 0 < l`] by auto - have "Ifloat l^n \ x^n" and "x^n \ Ifloat u^n " using assms unfolding atLeastAtMost_iff using power_mono_odd[OF False] by auto + have "Ifloat l ^ n \ x ^ n" and "x ^ n \ 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: "\ x l u. (l1, u1) = float_power_bnds n l u \ x \ {Ifloat l .. Ifloat u} \ Ifloat l1 \ x^n \ x^n \ Ifloat u1" +lemma bnds_power: "\ x l u. (l1, u1) = float_power_bnds n l u \ x \ {Ifloat l .. Ifloat u} \ Ifloat l1 \ x ^ n \ x ^ n \ 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: "\m. ((\i. i + 2) ^ n) m = m + 2 * n" by (induct n arbitrary: m, auto) - have "?f (Suc n) = ?f n * ((\i. i + 2) ^ n) 1 * (((\i. i + 2) ^ n) 1 + 1)" + have F: "\m. ((\i. i + 2) ^^ n) m = m + 2 * n" by (induct n arbitrary: m, auto) + have "?f (Suc n) = ?f n * ((\i. i + 2) ^^ n) 1 * (((\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 "(\ i=0.. i=0.. 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 + (\ j = 0 ..< n. 0)" by auto @@ -905,8 +905,8 @@ let "?f n" = "fact (2 * n + 1)" { fix n - have F: "\m. ((\i. i + 2) ^ n) m = m + 2 * n" by (induct n arbitrary: m, auto) - have "?f (Suc n) = ?f n * ((\i. i + 2) ^ n) 2 * (((\i. i + 2) ^ n) 2 + 1)" + have F: "\m. ((\i. i + 2) ^^ n) m = m + 2 * n" by (induct n arbitrary: m, auto) + have "?f (Suc n) = ?f n * ((\i. i + 2) ^^ n) 2 * (((\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) \ { 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: "\ m. ((\i. i + 1) ^ n) m = n + m" by (induct n, auto) - have "fact (Suc n) = fact n * ((\i. i + 1) ^ n) 1" unfolding F by auto } note f_eq = this + have F: "\ m. ((\i. i + 1) ^^ n) m = n + m" by (induct n, auto) + have "fact (Suc n) = fact n * ((\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 `\ 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 `\ 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 \ 0" @@ -1631,10 +1632,10 @@ lemma ln_bounds: assumes "0 \ x" and "x < 1" - shows "(\i=0..<2*n. -1^i * (1 / real (i + 1)) * x^(Suc i)) \ ln (x + 1)" (is "?lb") - and "ln (x + 1) \ (\i=0..<2*n + 1. -1^i * (1 / real (i + 1)) * x^(Suc i))" (is "?ub") + shows "(\i=0..<2*n. -1^i * (1 / real (i + 1)) * x ^ (Suc i)) \ ln (x + 1)" (is "?lb") + and "ln (x + 1) \ (\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: "(\ i. -1^i * ?a i) = ln (x + 1)" using ln_series[of "x + 1"] `0 \ 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') diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Decision_Procs/Dense_Linear_Order.thy --- 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 <" - "\ x y. 1/2 * ((x::'a::{ordered_field,recpower,number_ring}) + y)" + "\ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Decision_Procs/cooper_tac.ML --- 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*) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Decision_Procs/ex/Dense_Linear_Order_Ex.thy --- 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 - "\(y::'a::{ordered_field,recpower,number_ring, division_by_zero}) <2. x + 3* y < 0 \ x - y >0" + "\(y::'a::{ordered_field,number_ring, division_by_zero}) <2. x + 3* y < 0 \ 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) \ 0 )" +lemma "EX x. (ALL (y::'a::{ordered_field,number_ring, division_by_zero}). y < 2 --> 2*(y - x) \ 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 \ 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 \ 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) \ 0 \ (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) \ 0 \ (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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Decision_Procs/mir_tac.ML --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Deriv.thy --- 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 \ 'a::{real_normed_field,recpower}" + fixes f :: "'a \ 'a::{real_normed_field}" assumes f: "DERIV f x :> D" shows "DERIV (\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 \ 'a::{real_normed_field,recpower}" + fixes f :: "'a \ 'a::{real_normed_field}" assumes f: "DERIV f x :> D" shows "DERIV (\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 \ 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) \ 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) \ 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} \ 'a" + fixes f :: "'a::{real_normed_field} \ 'a" assumes "f differentiable x" shows "(\x. f x ^ n) differentiable x" by (induct n, simp, simp add: prems) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Divides.thy --- 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 \ 0 \ (a + c * b) div b = c + a div b" + and div_mult_mult1 [simp]: "c \ 0 \ (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 \ 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 \ 0 \ 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 \ z dvd y +lemma div_add [simp]: "z dvd x \ z dvd y \ (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 \ z dvd w \ (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 \ 0 \ (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 \ - z dvd w \ (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 \ - (x div y)^n = x^n div y^n" +lemma div_power: + "(y::'a::{semiring_div,no_zero_divisors,power}) dvd x \ + (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\nat"}(uotient) and @{term "r\nat"}(emainder). *} -definition divmod_rel :: "nat \ nat \ nat \ nat \ bool" where - "divmod_rel m n q r \ m = q * n + r \ (if n > 0 then 0 \ r \ r < n else q = 0)" +definition divmod_rel :: "nat \ nat \ nat \ nat \ bool" where + "divmod_rel m n qr \ + m = fst qr * n + snd qr \ + (if n = 0 then fst qr = 0 else if n > 0 then 0 \ snd qr \ snd qr < n else n < snd qr \ snd qr \ 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: "\q r q' r'. q' * n + r' = q * n + r \ r < n \ q' \ (q\nat)" @@ -450,18 +474,11 @@ apply (subst less_iff_Suc_add) apply (auto simp add: add_mult_distrib) done - from `n \ 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 \ 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 \ nat \ nat \ 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 \ 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 \ 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 \ 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]: "\n::nat. n div 0 = 0" + by (simp add: div_nat_def divmod_zero) + have [simp]: "\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 \ 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 \ 0" + then show "(m * n) div (m * q) = n div q" + proof (cases "n \ 0 \ q \ 0") + case False then show ?thesis by auto + next + case True with `m \ 0` + have "m > 0" and "n > 0" and "q > 0" by auto + then have "\a b. divmod_rel n q (a, b) \ 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\nat" n, standard] -lemmas mod_div_equality2_nat = mod_div_equality2 [of "n\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) \ c > 0 + \ 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) \ divmod_rel b c (bq, br) \ c > 0 + \ 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) \ 0 < b \ 0 < c + \ 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)]: "\m::nat. m \ n --> (m div k) \ (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 \ (n::nat)" -by (auto elim!: dvdE) (auto simp add: gr0_conv_Suc) - -lemma nat_dvd_not_less: "(0::nat) < m \ m < n \ \ 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 \ n" +lemma power_dvd_imp_le: + "i ^ m dvd i ^ n \ (1::nat) < i \ m \ 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 \ m < n \ \ n dvd m" +by (auto elim!: dvdE) (auto simp add: gr0_conv_Suc) + end diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Finite_Set.thy --- 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 \ 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 \ 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) \ finite A \ 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 \ Inl) A + setsum (f \ Inr) B" +proof - + have "A <+> B = Inl ` A \ 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 \ Inr ` B = ({} :: ('a + 'b) set)" by auto + moreover have "inj_on (Inl :: 'a \ 'a + 'b) A" "inj_on (Inr :: 'b \ '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 ==> (\x\ A. (y::'a::{recpower, comm_monoid_mult})) = y^(card A)" +lemma setprod_constant: "finite A ==> (\x\ 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 (\k. if k=a then b k else c) S = (if a \ S then (b a ::'a::{comm_monoid_mult, recpower}) * c^ (card S - 1) else c^ card S)" + shows "setprod (\k. if k=a then b k else c) S = (if a \ S then (b a ::'a::{comm_monoid_mult}) * c^ (card S - 1) else c^ card S)" proof- let ?f = "(\k. if k=a then b k else c)" {assume a: "a \ 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 \ 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Fun.thy --- 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 \ A then insert y (f ` (A-{x})) else f ` A)" by auto +lemma fun_upd_comp: "f \ (g(x := y)) = (f \ g)(x := f y)" +by(auto intro: ext) + subsection {* @{text override_on} *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Groebner_Basis.thy --- 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 \ z" hence ynz': "y - z \ 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"}])) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/HOL.thy --- 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 \ 'a \ bool" assumes eq_equals: "eq x y \ 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 \ True" unfolding eq by rule+ +lemma equals_eq [code inline]: "(op =) \ 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\{})" + +code_datatype Trueprop "prop" + +text {* Code equations *} + +lemma [code]: + shows "(True \ PROP P) \ PROP P" + and "(False \ Q) \ Trueprop True" + and "(PROP P \ True) \ Trueprop True" + and "(Q \ False) \ Trueprop (\ Q)" by (auto intro!: equal_intr_rule) + +lemma [code]: + shows "False \ x \ False" + and "True \ x \ x" + and "x \ False \ False" + and "x \ True \ x" by simp_all + +lemma [code]: + shows "False \ x \ x" + and "True \ x \ True" + and "x \ False \ x" + and "x \ True \ True" by simp_all + +lemma [code]: + shows "\ True \ False" + and "\ False \ 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 \ (\x. Let x f)" + shows "CASE x \ f x" + using assms by simp_all + +lemma If_case_cert: + assumes "CASE \ (\b. If b f g)" + shows "(CASE True \ f) &&& (CASE False \ 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 \ \ prop \ prop \ 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/HoareParallel/Graph.thy --- 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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/HoareParallel/OG_Tran.thy --- 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 \ 'a) \ nat \ ('a ann_com_op \ 'a) \ bool" ("_ -_\ _"[81,81] 100) where - "con_0 -n\ con_1 \ (con_0, con_1) \ ann_transition^n" + "con_0 -n\ con_1 \ (con_0, con_1) \ ann_transition ^^ n" abbreviation ann_transitions :: "('a ann_com_op \ 'a) \ ('a ann_com_op \ 'a) \ bool" @@ -84,7 +84,7 @@ abbreviation transition_n :: "('a com \ 'a) \ nat \ ('a com \ 'a) \ bool" ("_ -P_\ _"[81,81,81] 100) where - "con_0 -Pn\ con_1 \ (con_0, con_1) \ transition^n" + "con_0 -Pn\ con_1 \ (con_0, con_1) \ transition ^^ n" subsection {* Definition of Semantics *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/IMP/Compiler0.thy --- 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] \ bool" ("_ \/ (3\_,_\/ -(_)\ \_,_\)" [50,0,0,0,0,0] 50) where - "P \ \s,m\ -(i)\ \t,n\ == ((s,m),t,n) : ((stepa1 P)^i)" + "P \ \s,m\ -(i)\ \t,n\ == ((s,m),t,n) : (stepa1 P ^^ i)" subsection "The compiler" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/IMP/Machines.thy --- 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 \ (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) \ R^n) = (n=0 \ z=x \ (\m y. n = Suc m \ (x,y) \ R \ (y,z) \ R^m))" + "((x,z) \ R ^^ n) = (n=0 \ z=x \ (\m y. n = Suc m \ (x,y) \ R \ (y,z) \ 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: "\ (x,y) \ R^m; (y,z) \ R^n \ \ (x,z) \ R^(m+n)" +lemma rel_pow_plusI: + "\ (x,y) \ R ^^ m; (y,z) \ R ^^ n \ \ (x,z) \ 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] \ bool" ("(_/ \ (1\_,/_\)/ -_\ (1\_,/_\))" [50,0,0,0,0] 50) where - "p \ \i,s\ -n\ \j,t\ == ((i,s),j,t) : (exec01 p)^n" + "p \ \i,s\ -n\ \j,t\ == ((i,s),j,t) : (exec01 p)^^n" subsection "M0 with lists" @@ -89,7 +90,7 @@ abbreviation stepan :: "[instrs,instrs,state, nat, instrs,instrs,state] \ bool" ("((1\_,/_,/_\)/ -_\ (1\_,/_,/_\))" 50) where - "\p,q,s\ -i\ \p',q',t\ == ((p,q,s),p',q',t) : (stepa1^i)" + "\p,q,s\ -i\ \p',q',t\ == ((p,q,s),p',q',t) : (stepa1^^i)" inductive_cases execE: "((i#is,p,s), (is',p',s')) : stepa1" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/IMP/Transition.thy --- 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\state),nat,(com option\state)] \ bool" ("_ -_\\<^sub>1 _" [60,60,60] 60) where - "cs -n\\<^sub>1 cs' == (cs,cs') \ evalc1^n" + "cs -n\\<^sub>1 cs' == (cs,cs') \ evalc1^^n" abbreviation evalc' :: "[(com option\state),(com option\state)] \ bool" @@ -77,28 +76,9 @@ "cs \\<^sub>1\<^sup>* cs' == (cs,cs') \ evalc1^*" (*<*) -(* fixme: move to Relation_Power.thy *) -lemma rel_pow_Suc_E2 [elim!]: - "[| (x, z) \ R ^ Suc n; !!y. [| (x, y) \ R; (y, z) \ R ^ n |] ==> P |] ==> P" - by (blast dest: rel_pow_Suc_D2) +declare rel_pow_Suc_E2 [elim!] +(*>*) -lemma rtrancl_imp_rel_pow: "p \ R^* \ \n. p \ R^n" -proof (induct p) - fix x y - assume "(x, y) \ R\<^sup>*" - thus "\n. (x, y) \ R^n" - proof induct - fix a have "(a, a) \ R^0" by simp - thus "\n. (a, a) \ R ^ n" .. - next - fix a b c assume "\n. (a, b) \ R ^ n" - then obtain n where "(a, b) \ R^n" .. - moreover assume "(b, c) \ R" - ultimately have "(a, c) \ R^(Suc n)" by auto - thus "\n. (a, c) \ 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]: "\s\ -n\\<^sub>1 y = (n = 0 \ y = \s\)" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Imperative_HOL/Heap_Monad.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Import/HOL/HOL4Base.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Import/HOL/HOL4Word32.thy --- 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 - diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Import/HOL/arithmetic.imp --- 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" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Import/HOL/real.imp --- 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" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Import/HOL4Compat.thy --- 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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Import/HOLLight/hollight.imp --- 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" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Int.thy --- 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 \ 'a" -where +definition of_int :: "int \ 'a" where [code del]: "of_int z = contents (\(i, j) \ 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 ("\") -context ring_1 -begin - lemma Ints_0 [simp]: "0 \ \" 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\int)" - | "p ^ (Suc n) = (p\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) \ (x \ (0::int) | n = 0)" - by (induct n) (auto simp add: zero_less_mult_iff) - -lemma zero_le_zpower_abs [simp]: "(0::int) \ 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) \ (x \ (0::int) | n = 0)" + by (rule zero_less_power_abs_iff) + +lemma zero_le_zpower_abs: "(0::int) \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/IntDiv.thy --- 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 \ int \ int \ int \ 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 \ 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 \ 0" + then show "(a * b) div (a * c) = b div c" + proof (cases "b \ 0 \ c \ 0") + case False then show ?thesis by auto + next + case True then have "b \ 0" and "c \ 0" by auto + with `a \ 0` + have "\q r. divmod_rel b c (q, r) \ 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 \ 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 \ 0` `c \ 0` have "a * c \ 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 \ 0 |] ==> (c*a) div (c*b) = a div b" -by (subst zdiv_zmult2_eq, auto) - -lemma zdiv_zmult_zmult1_aux2: - "[| b < (0::int); c \ 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 \ (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 \ 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 \ 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 \ 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 \ int \ int \ int" where diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/IsaMakefile --- 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 \ diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Binomial.thy --- 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} \ nat \ 'a" (infixl "gchoose" 65) +definition gbinomial :: "'a::{field, ring_char_0} \ nat \ 'a" (infixl "gchoose" 65) where "a gchoose n = (if n = 0 then 1 else (setprod (\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 (\i. a - of_nat i) {0 .. k})" + "(of_nat (fact (Suc k)) :: 'a) * ((a::'a::{field, ring_char_0}) gchoose (Suc k)) = (setprod (\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 (\i. a - of_nat i) {0 .. k})" + "((a::'a::{field, ring_char_0}) gchoose (Suc k)) * (of_nat (fact (Suc k)) :: 'a) = (setprod (\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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Code_Char.thy --- 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 \ char \ term" - (SML "HOLogic.mk'_char/ (IntInf.fromInt/ (Char.ord/ _))") + (Eval "HOLogic.mk'_char/ (IntInf.fromInt/ (Char.ord/ _))") end diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Code_Index.thy --- 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 \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Coinductive_List.thy --- 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 \ '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) \ - {((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 "\ = LCons ((f ^ n) u) ((lmap f ^ n) (lmap f (h u)))" + also have "\ = 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 "\ = LCons ((f ^ n) u) ((lmap f ^ n) (iterates f (f u)))" + also have "\ = 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Commutative_Ring.thy --- 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 \ 'a pol \ 'a" +primrec + Ipol :: "'a::{comm_ring_1} list \ 'a pol \ '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 \ 'a polex \ 'a" +primrec + Ipolex :: "'a::{comm_ring_1} list \ 'a polex \ '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 \ Pinj x P)" definition - mkPX :: "'a::{comm_ring,recpower} pol \ nat \ 'a pol \ 'a pol" where + mkPX :: "'a::{comm_ring} pol \ nat \ 'a pol \ 'a pol" where "mkPX P i Q = (case P of Pc c \ (if (c = 0) then (mkPinj 1 Q) else (PX P i Q)) | Pinj j R \ PX P i Q | @@ -63,7 +63,7 @@ text {* Defining the basic ring operations on normalized polynomials *} function - add :: "'a::{comm_ring,recpower} pol \ 'a pol \ 'a pol" (infixl "\" 65) + add :: "'a::{comm_ring} pol \ 'a pol \ 'a pol" (infixl "\" 65) where "Pc a \ Pc b = Pc (a + b)" | "Pc c \ Pinj i P = Pinj i (P \ Pc c)" @@ -90,7 +90,7 @@ termination by (relation "measure (\(x, y). size x + size y)") auto function - mul :: "'a::{comm_ring,recpower} pol \ 'a pol \ 'a pol" (infixl "\" 70) + mul :: "'a::{comm_ring} pol \ 'a pol \ 'a pol" (infixl "\" 70) where "Pc a \ Pc b = Pc (a * b)" | "Pc c \ Pinj i P = @@ -122,8 +122,8 @@ (auto simp add: mkPinj_def split: pol.split) text {* Negation*} -fun - neg :: "'a::{comm_ring,recpower} pol \ 'a pol" +primrec + neg :: "'a::{comm_ring} pol \ '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 \ 'a pol \ 'a pol" (infixl "\" 65) + sub :: "'a::{comm_ring} pol \ 'a pol \ 'a pol" (infixl "\" 65) where "sub P Q = P \ neg Q" text {* Square for Fast Exponentation *} -fun - sqr :: "'a::{comm_ring,recpower} pol \ 'a pol" +primrec + sqr :: "'a::{comm_ring_1} pol \ '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 \ 'a::{comm_ring,recpower} pol \ 'a pol" + pow :: "nat \ 'a::{comm_ring_1} pol \ '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 \ 'a pol" +primrec + norm :: "'a::{comm_ring_1} polex \ 'a pol" where "norm (Pol P) = P" | "norm (Add P Q) = norm P \ norm Q" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Continuity.thy --- 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 \ lfp F" + { fix i have "(F ^^ i) bot \ lfp F" proof (induct i) - show "(F^0) bot \ lfp F" by simp + show "(F ^^ 0) bot \ 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 "\ \ F(lfp F)" by(rule monoD[OF mono Suc]) also have "\ = lfp F" by(simp add:lfp_unfold[OF mono, symmetric]) finally show ?case . qed } - hence "(SUP i. (F^i) bot) \ lfp F" by (blast intro!:SUP_leI) - moreover have "lfp F \ (SUP i. (F^i) bot)" (is "_ \ ?U") + hence "(SUP i. (F ^^ i) bot) \ lfp F" by (blast intro!:SUP_leI) + moreover have "lfp F \ (SUP i. (F ^^ i) bot)" (is "_ \ ?U") proof (rule lfp_lowerbound) - have "chain(%i. (F^i) bot)" + have "chain(%i. (F ^^ i) bot)" proof - - { fix i have "(F^i) bot \ (F^(Suc i)) bot" + { fix i have "(F ^^ i) bot \ (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 "\ \ ?U" by(fast intro:SUP_leI le_SUPI) finally show "F ?U \ ?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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Efficient_Nat.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Euclidean_Space.thy --- 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 ^ \ 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 \ 0" and Fp: "\ a \ F. f a \ 0" by simp_all from insert.hyps Fp setsum_nonneg[OF Fp] have h: "setsum f F = 0 \ (\a \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 (\i. x^i) {0 .. n} = (1 - x^(Suc n))" +lemma sum_gp_basic: "((1::'a::{field}) - x) * setsum (\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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Eval_Witness.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Float.thy --- 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 \ real" where -"Ifloat (Float a b) = real a * pow2 b" +primrec Ifloat :: "float \ 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 \ int" where -"mantissa (Float a b) = a" +primrec mantissa :: "float \ int" where + "mantissa (Float a b) = a" -fun scale :: "float \ int" where -"scale (Float a b) = b" +primrec scale :: "float \ int" where + "scale (Float a b) = b" lemma Ifloat_neg_exp: "e < 0 \ Ifloat (Float m e) = real m * inverse (2^nat (-e))" by auto lemma Ifloat_nge0_exp: "\ 0 \ e \ 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 \ float" where -"float_pprt (Float a e) = (if 0 <= a then (Float a e) else 0)" +primrec float_pprt :: "float \ float" where + "float_pprt (Float a e) = (if 0 <= a then (Float a e) else 0)" -fun float_nprt :: "float \ float" where -"float_nprt (Float a e) = (if 0 <= a then 0 else (Float a e))" +primrec float_nprt :: "float \ 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 \ w \ Ifloat z \ 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 \ 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 \ float \ float" where +primrec round_down :: "nat \ float \ 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 \ float \ float" where +primrec round_up :: "nat \ float \ 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 \ float" where -"float_abs (Float m e) = Float \m\ e" +primrec float_abs :: "float \ float" where + "float_abs (Float m e) = Float \m\ e" instantiation float :: abs begin definition abs_float_def: "\x\ = 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 \ float" where -"floor_fl (Float m e) = (if 0 \ e then Float m e +primrec floor_fl :: "float \ float" where + "floor_fl (Float m e) = (if 0 \ e then Float m e else Float (m div (2 ^ (nat (-e)))) 0)" lemma floor_fl: "Ifloat (floor_fl x) \ Ifloat x" @@ -1358,8 +1329,8 @@ declare floor_fl.simps[simp del] -fun ceiling_fl :: "float \ float" where -"ceiling_fl (Float m e) = (if 0 \ e then Float m e +primrec ceiling_fl :: "float \ float" where + "ceiling_fl (Float m e) = (if 0 \ e then Float m e else Float (m div (2 ^ (nat (-e))) + 1) 0)" lemma ceiling_fl: "Ifloat x \ Ifloat (ceiling_fl x)" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Formal_Power_Series.thy --- 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 \ 'a fps \ '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 \ 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 \ 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) \ 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) \ n > 0 \ 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}) \ 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}) \ 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}) \ (n \ 0 \ a$0 = 0)" + "a^n $0 = (0::'a::{idom}) \ (n \ 0 \ 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 (\n. if n = 1 then 1 else 0)" @@ -901,7 +883,7 @@ lemma X_power_iff: "X^k = Abs_fps (\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 (\n. (- (1::'a::{recpower, field})) ^ n)" (is "_ = ?r") + "inverse (1 + X) = Abs_fps (\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 (\i. a_i * x^i))/x^h, for h>0*) lemma fps_power_mult_eq_shift: - "X^Suc k * Abs_fps (\n. a (n + Suc k)) = Abs_fps a - setsum (\i. fps_const (a i :: 'a:: field) * X^i) {0 .. k}" (is "?lhs = ?rhs") + "X^Suc k * Abs_fps (\n. a (n + Suc k)) = Abs_fps a - setsum (\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 (\i. fps_const (a i :: 'a:: field) * X^i) {0 .. Suc k})$n = (Abs_fps a - setsum (\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 (\i. fps_const (a i :: 'a) * X^i) {0 .. Suc k})$n = (Abs_fps a - setsum (\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 "\ = (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 (\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 (\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 (\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 \ 0" shows "(b oo a = c oo a) \ b = c" (is "?lhs \?rhs") proof- @@ -1366,7 +1351,7 @@ subsection {* Radicals *} declare setprod_cong[fundef_cong] -function radical :: "(nat \ 'a \ 'a) \ nat \ ('a::{field, recpower}) fps \ nat \ 'a" where +function radical :: "(nat \ 'a \ 'a) \ nat \ ('a::{field}) fps \ nat \ '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 \ 0" + shows "(r (Suc k) (a$0)) ^ Suc k = a$0 \ (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) \ 0" by auto + {fix z have "?r ^ Suc k $ z = a$z" + proof(induct z rule: nat_less_induct) + fix n assume H: "\m 0" using n1 by arith + let ?Pnk = "natpermute n (k + 1)" + let ?Pnkn = "{xs \ ?Pnk. n \ set xs}" + let ?Pnknn = "{xs \ ?Pnk. n \ set xs}" + have eq: "?Pnkn \ ?Pnknn = ?Pnk" by blast + have d: "?Pnkn \ ?Pnknn = {}" by blast + have f: "finite ?Pnkn" "finite ?Pnknn" + using finite_Un[of ?Pnkn ?Pnknn, unfolded eq] + by (metis natpermute_finite)+ + let ?f = "\v. \j\{0..k}. ?r $ v ! j" + have "setsum ?f ?Pnkn = setsum (\v. ?r $ n * r (Suc k) (a $ 0) ^ k) ?Pnkn" + proof(rule setsum_cong2) + fix v assume v: "v \ {xs \ natpermute n (k + 1). n \ set xs}" + let ?ths = "(\j\{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 \ {0..k}" "v = replicate (k+1) 0 [i:= n]" + unfolding natpermute_contain_maximal by auto + have "(\j\{0..k}. fps_radical r (Suc k) a $ v ! j) = (\j\{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 "\ = (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 "\ = 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 "\ = 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 \ 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 \ 0" + and a0: "r (Suc k) (b$0 ::'a::{field, ring_char_0}) = a$0" and b0: "b$0 \ 0" shows "a^(Suc k) = b \ a = fps_radical r (Suc k) b" proof- let ?r = "fps_radical r (Suc k) b" have r00: "r (Suc k) (b$0) \ 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}) \ 0" + and a0: "(a$0 ::'a::{field, ring_char_0}) \ 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 \ 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 \ 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 \ 0" + and b0: "b$0 \ 0" + shows "r k ((a * b) $ 0) = r k (a $ 0) * r k (b $ 0) \ 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 \ 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 \ 0" and b0: "b$0 \ 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 \ 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) \ 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 \ 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 \ 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 \ 0" and b0: "b$0 \ 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) \ 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\ 0" - from b0 k0 rb0 have rbn0: "r k (b $0) \ 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) \ 0" using a0 ra0 k by auto + have rb0': "r k (b$0) \ 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 \ 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 \ 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 \ 0" + shows "r k (inverse (a $ 0)) = r k 1 / (r k (a $ 0)) \ 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 \ nat \ 'a::{recpower,field}" where +fun compinv :: "'a fps \ nat \ 'a::{field}" where "compinv a 0 = X$0" | "compinv a (Suc n) = (X$ Suc n - setsum (\i. (compinv a i) * (a^i)$Suc n) {0 .. n}) / (a$1) ^ Suc n" @@ -1862,7 +1914,7 @@ qed -fun gcompinv :: "'a fps \ 'a fps \ nat \ 'a::{recpower,field}" where +fun gcompinv :: "'a fps \ 'a fps \ nat \ 'a::{field}" where "gcompinv b a 0 = b$0" | "gcompinv b a (Suc n) = (b$ Suc n - setsum (\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 (\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 \ 0" + assumes a0:"a$0 = (0::'a::{field})" and a1: "a$1 \ 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 (\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 \ a = fps_const (a$0) * E (c :: 'a::{field, ring_char_0, recpower})" + "fps_deriv a = fps_const c * a \ a = fps_const (a$0) * E (c :: 'a::{field, ring_char_0})" (is "?lhs \ ?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 (\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 (\n. (- 1 ::'a::{field, recpower})^n)" + "inverse (1 + X) = Abs_fps (\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 (\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\ (0::'a::{field,division_by_zero,ring_char_0,recpower})" + assumes a: "a\ (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 (\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 (\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 (\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 "\ = 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/FrechetDeriv.thy --- 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 (\x. x ^ Suc n) x :> (\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 (\x. x ^ n) x :> (\h. of_nat n * x ^ (n - 1) * h)" apply (cases n) apply (simp add: FDERIV_const) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Fundamental_Theorem_Algebra.thy --- 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: "\(\z. z\0 \ poly p z = (0::'a::{recpower,idom}))" + assumes nz: "\(\z. z\0 \ poly p z = (0::'a::{idom}))" shows "\k a q. a\0 \ Suc (psize q + k) = psize p \ (\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 "\k a q. a\(0::'a::{recpower,idom}) \ k\0 \ + shows "\k a q. a\(0::'a::{idom}) \ k\0 \ psize q + k + 1 = psize p \ (\z. poly p z = poly p 0 + z^k * poly (pCons a q) z)" using nc diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Library.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Nat_Infinity.thy --- 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 ("\") +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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Numeral_Type.thy --- 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) \ 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} \ int" - and Abs :: "int \ 'a::{zero,one,plus,times,uminus,minus,power}" + and Rep :: "'a::{zero,one,plus,times,uminus,minus} \ int" + and Abs :: "int \ 'a::{zero,one,plus,times,uminus,minus}" assumes type: "type_definition Rep Abs {0.. int" - and Abs :: "int \ 'a::{number_ring,power}" + and Rep :: "'a::{number_ring} \ int" + and Abs :: "int \ '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) \ 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 \ '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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Pocklington.thy --- 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 (\m. (c::'a::{comm_monoid_mult,recpower})* a(m)) S = c ^ (card S) * setprod a S" + shows "setprod (\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: diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Polynomial.thy --- 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 \ 0 \ p dvd smult a q \ 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) \ 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 \ 0" + show "(x * y) div (x * z) = y div z" + proof (cases "y \ 0 \ z \ 0") + have "\x::'a poly. pdivmod_rel x 0 0 x" + by (rule pdivmod_rel_by_0) + then have [simp]: "\x::'a poly. x div 0 = 0" + by (rule div_poly_eq) + have "\x::'a poly. pdivmod_rel 0 x 0 0" + by (rule pdivmod_rel_0) + then have [simp]: "\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 \ 0" and "z \ 0" by auto + with `x \ 0` + have "\q r. pdivmod_rel y z q r \ 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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Preorder.thy --- /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 \ 'a \ bool" where + "equiv x y \ x \ y \ y \ x" + +notation + equiv ("op ~~") and + equiv ("(_/ ~~ _)" [51, 51] 50) + +notation (xsymbols) + equiv ("op \") and + equiv ("(_/ \ _)" [51, 51] 50) + +notation (HTML output) + equiv ("op \") and + equiv ("(_/ \ _)" [51, 51] 50) + +lemma refl [iff]: + "x \ x" + unfolding equiv_def by simp + +lemma trans: + "x \ y \ y \ z \ x \ z" + unfolding equiv_def by (auto intro: order_trans) + +lemma antisym: + "x \ y \ y \ x \ x \ y" + unfolding equiv_def .. + +lemma less_le: "x < y \ x \ y \ \ x \ y" + by (auto simp add: equiv_def less_le_not_le) + +lemma le_less: "x \ y \ x < y \ x \ y" + by (auto simp add: equiv_def less_le) + +lemma le_imp_less_or_eq: "x \ y \ x < y \ x \ y" + by (simp add: less_le) + +lemma less_imp_not_eq: "x < y \ x \ y \ False" + by (simp add: less_le) + +lemma less_imp_not_eq2: "x < y \ y \ x \ False" + by (simp add: equiv_def less_le) + +lemma neq_le_trans: "\ a \ b \ a \ b \ a < b" + by (simp add: less_le) + +lemma le_neq_trans: "a \ b \ \ a \ b \ a < b" + by (simp add: less_le) + +lemma antisym_conv: "y \ x \ x \ y \ x \ y" + by (simp add: equiv_def) + +end + +end diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Primes.thy --- 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: "\p. prime p \ p > n" using euclid_bound by auto + lemma primes_infinite: "\ (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 \ {}" 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 \ ?P" . - from Max_ge [OF fP] have contr: "\ p. prime p \ p \ ?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 \ p dvd a \ p dvd b)" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Product_ord.thy --- 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 \ y \ fst x < fst y \ fst x = fst y \ snd x \ snd y" + prod_le_def [code del]: "x \ y \ fst x < fst y \ fst x \ fst y \ snd x \ snd y" definition - prod_less_def [code del]: "x < y \ fst x < fst y \ fst x = fst y \ snd x < snd y" + prod_less_def [code del]: "x < y \ fst x < fst y \ fst x \ fst y \ snd x < snd y" instance .. end lemma [code]: - "(x1\'a\{ord, eq}, y1) \ (x2, y2) \ x1 < x2 \ x1 = x2 \ y1 \ y2" - "(x1\'a\{ord, eq}, y1) < (x2, y2) \ x1 < x2 \ x1 = x2 \ y1 < y2" + "(x1\'a\{ord, eq}, y1) \ (x2, y2) \ x1 < x2 \ x1 \ x2 \ y1 \ y2" + "(x1\'a\{ord, eq}, y1) < (x2, y2) \ x1 < x2 \ x1 \ x2 \ 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 \ 'a \ 'b \ _ \ _) = 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Quickcheck.thy --- 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 \ '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 \ typerep \ ('a \ 'a \ bool) \ ('a \ term) + \ (seed \ ('b \ (unit \ term)) \ seed) \ (seed \ seed \ seed) + \ seed \ (('a \ 'b) \ (unit \ term)) \ 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 \ seed \ (('a \ 'b) \ (unit \ term)) \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/State_Monad.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Topology_Euclidean_Space.thy --- 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 \ s" by auto - def z \ "\ n::nat. fun_pow n f z0" + def z \ "\n. (f ^^ n) z0" { fix n::nat have "z n \ s" unfolding z_def proof(induct n) case 0 thus ?case using `z0 \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 \ "g x" have [simp]:"y\s" unfolding y_def using gs[unfolded image_subset_iff] and `x\s` by blast - def f \ "\ n. fun_pow n g" + def f \ "\n. g ^^ n" have [simp]:"\n z. g (f n z) = f (Suc n) z" unfolding f_def by auto have [simp]:"\z. f 0 z = z" unfolding f_def by auto { fix n::nat and z assume "z\s" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Univ_Poly.thy --- 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 \ 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) \ poly [])" +lemma (in idom) poly_exp_prime_eq_zero: "(poly ([a, 1] %^ n) \ 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 \ n ==> (p %^ m) divides (p %^ n)" +lemma (in comm_semiring_1) poly_divides_exp: "m \ 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\n |] ==> (p %^ m) divides q" +lemma (in comm_semiring_1) poly_exp_divides: "[| (p %^ n) divides q; m\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 \ poly []" shows "\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 \ poly [] +lemma (in idom_char_0) poly_order: "poly p \ 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 \ poly [] |] +lemma (in idom_char_0) order2: "[| poly p \ 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 \ poly []; ([-a, 1] %^ n) divides p; +lemma (in idom_char_0) order_unique: "[| poly p \ 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 \ poly [] & ([-a, 1] %^ n) divides p & +lemma (in idom_char_0) order_unique_lemma: "(poly p \ 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 \ 0)" +lemma (in idom_char_0) order_root: "(poly p a = 0) = ((poly p = poly []) | order a p \ 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 \ order a p)" +lemma (in idom_char_0) order_divides: "(([-a, 1] %^ n) divides p) = ((poly p = poly []) | n \ 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 \ poly [] ==> \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) \ 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) \ 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 \ poly [] ==> (poly p a = 0) = (order a p \ 0)" +lemma (in idom_char_0) order_root2: "poly p \ poly [] ==> (poly p a = 0) = (order a p \ 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 |] ==> \q. (poly p = poly ([-a, 1] *** q)) & poly q a \ 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 \ poly []" shows "order a p \ degree p" proof- diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/Word.thy --- 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 ("\") | One ("\") -primrec - bitval :: "bit => nat" -where - "bitval \ = 0" +primrec bitval :: "bit => nat" where + "bitval \ = 0" | "bitval \ = 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 . diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/comm_ring.ML --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Library/reflection.ML --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Lim.thy --- 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 \ 'b::{recpower,real_normed_algebra}" + fixes f :: "'a::real_normed_vector \ 'b::{power,real_normed_algebra}" assumes f: "f -- a --> l" shows "(\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 \ 'b::{recpower,real_normed_algebra}" + fixes f :: "'a::real_normed_vector \ 'b::{power,real_normed_algebra}" shows "isCont f a \ isCont (\x. f x ^ n) a" unfolding isCont_def by (rule LIM_power) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/List.thy --- 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 \ 'a list \ '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] = [] \ 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 \ x \ 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 \ [] \ 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 & \ 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 (\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 \ ('b::comm_monoid_add)" +shows "x : set xs \ 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 \ 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 \ 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 \ ?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 \ UNIV)" -proof (rule UNIV_eq_I) - fix x show "x \ image (split Char) (UNIV \ 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 \ nibble \ 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 \ is_measure (list_size f)" @@ -3518,10 +3488,35 @@ "(\x. x \ set xs \ f x < g x) \ list_size f xs \ 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 \ 'a\eq list \ 'a list \ 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 \ 'a\eq list \ 'a list \ 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Map.thy --- 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 = {} \ 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: "\ f \\<^sub>m h; g \\<^sub>m h; f \\<^sub>m f++g \ \ f++g \\<^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} \ (\v. f = [x \ v])" +proof(rule iffI) + assume "\v. f = [x \ 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 \ v] \\<^sub>m f" by(auto simp add: map_le_def) + moreover have "f \\<^sub>m [x \ v]" using `dom f = {x}` `f x = Some v` + by(auto simp add: map_le_def) + ultimately have "f = [x \ v]" by-(rule map_le_antisym) + thus "\v. f = [x \ v]" by blast +qed + end diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/MicroJava/Comp/CorrCompTp.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/NSA/HDeriv.thy --- 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 \ 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 \ 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) \ 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) \ 0 |] ==> NSDERIV (%y. f(y) / (g y)) x :> (d*g(x) - (e*f(x))) / (g(x) ^ Suc (Suc 0))" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/NSA/HSEQ.thy --- 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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/NSA/HyperDef.thy --- 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 \ HFinite ==> x ^ n \ 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]: - "\n. (0::'a::{recpower,semiring_0} star) pow (n + (1::hypnat)) = 0" + "\n. (0::'a::{power,semiring_0} star) pow (n + (1::hypnat)) = 0" by transfer simp lemma hyperpow_not_zero: - "\r n. r \ (0::'a::{recpower,field} star) ==> r pow n \ 0" + "\r n. r \ (0::'a::{field} star) ==> r pow n \ 0" by transfer (rule field_power_not_zero) lemma hyperpow_inverse: - "\r n. r \ (0::'a::{recpower,division_by_zero,field} star) + "\r n. r \ (0::'a::{division_by_zero,field} star) \ inverse (r pow n) = (inverse r) pow n" by transfer (rule power_inverse) - + lemma hyperpow_hrabs: - "\r n. abs (r::'a::{recpower,ordered_idom} star) pow n = abs (r pow n)" + "\r n. abs (r::'a::{ordered_idom} star) pow n = abs (r pow n)" by transfer (rule power_abs [symmetric]) lemma hyperpow_add: - "\r n m. (r::'a::recpower star) pow (n + m) = (r pow n) * (r pow m)" + "\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]: - "\r. (r::'a::recpower star) pow (1::hypnat) = r" + "\r. (r::'a::monoid_mult star) pow (1::hypnat) = r" by transfer (rule power_one_right) lemma hyperpow_two: - "\r. (r::'a::recpower star) pow ((1::hypnat) + (1::hypnat)) = r * r" -by transfer (simp add: power_Suc) + "\r. (r::'a::monoid_mult star) pow ((1::hypnat) + (1::hypnat)) = r * r" +by transfer simp lemma hyperpow_gt_zero: - "\r n. (0::'a::{recpower,ordered_semidom} star) < r \ 0 < r pow n" + "\r n. (0::'a::{ordered_semidom} star) < r \ 0 < r pow n" by transfer (rule zero_less_power) lemma hyperpow_ge_zero: - "\r n. (0::'a::{recpower,ordered_semidom} star) \ r \ 0 \ r pow n" + "\r n. (0::'a::{ordered_semidom} star) \ r \ 0 \ r pow n" by transfer (rule zero_le_power) lemma hyperpow_le: - "\x y n. \(0::'a::{recpower,ordered_semidom} star) < x; x \ y\ + "\x y n. \(0::'a::{ordered_semidom} star) < x; x \ y\ \ x pow n \ y pow n" by transfer (rule power_mono [OF _ order_less_imp_le]) lemma hyperpow_eq_one [simp]: - "\n. 1 pow n = (1::'a::recpower star)" + "\n. 1 pow n = (1::'a::monoid_mult star)" by transfer (rule power_one) lemma hrabs_hyperpow_minus_one [simp]: - "\n. abs(-1 pow n) = (1::'a::{number_ring,recpower,ordered_idom} star)" + "\n. abs(-1 pow n) = (1::'a::{number_ring,ordered_idom} star)" by transfer (rule abs_power_minus_one) lemma hyperpow_mult: - "\r s n. (r * s::'a::{comm_monoid_mult,recpower} star) pow n + "\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) \ r pow (1 + 1)" + "(0::'a::{monoid_mult,ordered_ring_strict} star) \ 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\x"}*} @@ -511,11 +511,11 @@ by (simp add: Ring_and_Field.mult_strict_mono order_less_imp_le) lemma hyperpow_two_gt_one: - "\r::'a::{recpower,ordered_semidom} star. 1 < r \ 1 < r pow (1 + 1)" + "\r::'a::{ordered_semidom} star. 1 < r \ 1 < r pow (1 + 1)" by transfer (simp add: power_gt1 del: power_Suc) lemma hyperpow_two_ge_one: - "\r::'a::{recpower,ordered_semidom} star. 1 \ r \ 1 \ r pow (1 + 1)" + "\r::'a::{ordered_semidom} star. 1 \ r \ 1 \ r pow (1 + 1)" by transfer (simp add: one_le_power del: power_Suc) lemma two_hyperpow_ge_one [simp]: "(1::hypreal) \ 2 pow n" @@ -565,7 +565,7 @@ lemma of_hypreal_hyperpow: "\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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/NSA/NSA.thy --- 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: - "\(x::'a::{real_normed_div_algebra,recpower} star) n. + "\(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 \ HFinite ==> x ^ n \ HFinite" -apply (induct_tac "n") +apply (induct n) apply (auto simp add: power_Suc intro: HFinite_mult) done lemma HFinite_bounded: "[|(x::hypreal) \ HFinite; y \ x; 0 \ y |] ==> y \ HFinite" -apply (case_tac "x \ 0") +apply (cases "x \ 0") apply (drule_tac y = x in order_trans) apply (drule_tac [2] order_antisym) apply (auto simp add: linorder_not_le) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/NSA/NSComplex.thy --- 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]: - "\n. 0 pow (hSuc n) = (0::'a::{recpower,semiring_0} star)" + "\n. 0 pow (hSuc n) = (0::'a::{power,semiring_0} star)" by transfer (rule power_0_Suc) lemma hcpow_not_zero [simp,intro]: diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/NSA/StarDef.thy --- 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 ^) \ \x n. ( *f* (\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: "\x \ Standard; y \ Standard\ \ x mod y \ Standard" by (simp add: star_mod_def) -lemma Standard_power: "x \ Standard \ x ^ n \ 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 ^) \ \x n. ( *f* (\x. x ^ n)) x" +proof (rule eq_reflection, rule ext, rule ext) + fix n :: nat + show "\x::'a star. x ^ n = ( *f* (\x. x ^ n)) x" + proof (induct n) + case 0 + have "\x::'a star. ( *f* (\x. 1)) x = 1" + by transfer simp + then show ?case by simp + next + case (Suc n) + have "\x::'a star. x * ( *f* (\x\'a. x ^ n)) x = ( *f* (\x\'a. x * x ^ n)) x" + by transfer simp + with Suc show ?case by simp + qed +qed -instance star :: (recpower) recpower -proof - show "\a::'a star. a ^ 0 = 1" - by transfer (rule power_0) -next - fix n show "\a::'a star. a ^ Suc n = a * a ^ n" - by transfer (rule power_Suc) -qed +lemma Standard_power [simp]: "x \ Standard \ x ^ n \ 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/NSA/hypreal_arith.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Nat.thy --- 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 \ ('a \ 'b) \ ('a \ 'b)" + +abbreviation compower :: "('a \ 'b) \ nat \ 'a \ 'b" (infixr "^^" 80) where + "f ^^ n \ 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 \ ('a \ 'a) \ ('a \ 'a)" +begin + +primrec funpow :: "nat \ ('a \ 'a) \ 'a \ 'a" where + "funpow 0 f = id" + | "funpow (Suc n) f = f o funpow n f" + +end + +text {* for code generation *} + +definition funpow :: "nat \ ('a \ 'a) \ 'a \ '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 \ 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 "\ = (f ^^ n o f ^^ 1) x" by (simp only: funpow_add) + also have "\ = (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 (\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 \ 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 \ 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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/NatBin.thy --- 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" ("(_\)" [1000] 999) where - "x\ == x^2" - -notation (latex output) - power2 ("(_\)" [1000] 999) - -notation (HTML output) - power2 ("(_\)" [1000] 999) - - -subsection {* Predicate for negative binary numbers *} - -definition neg :: "int \ bool" where - "neg Z \ 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 \ 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 \ 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) \ 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' \ - (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) \ number_of v' \ - (if v \ v' then True else v \ 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)\ = a * a" - by (simp add: numeral_2_eq_2 Power.power_Suc) - -lemma zero_power2 [simp]: "(0::'a::{semiring_1,recpower})\ = 0" - by (simp add: power2_eq_square) - -lemma one_power2 [simp]: "(1::'a::{semiring_1,recpower})\ = 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 \ (a\::'a::{ordered_idom,recpower})" - by (simp add: power2_eq_square) - -lemma zero_less_power2[simp]: - "(0 < a\) = (a \ (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\ < 0)" -by (force simp add: power2_eq_square mult_less_0_iff) - -lemma zero_eq_power2[simp]: - "(a\ = 0) = (a = (0::'a::{ordered_idom,recpower}))" - by (force simp add: power2_eq_square mult_eq_0_iff) - -lemma abs_power2[simp]: - "abs(a\) = (a\::'a::{ordered_idom,recpower})" - by (simp add: power2_eq_square abs_mult abs_mult_self) - -lemma power2_abs[simp]: - "(abs a)\ = (a\::'a::{ordered_idom,recpower})" - by (simp add: power2_eq_square abs_mult_self) - -lemma power2_minus[simp]: - "(- a)\ = (a\::'a::{comm_ring_1,recpower})" - by (simp add: power2_eq_square) - -lemma power2_le_imp_le: - fixes x y :: "'a::{ordered_semidom,recpower}" - shows "\x\ \ y\; 0 \ y\ \ x \ 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 "\x\ < y\; 0 \ y\ \ x < y" -by (rule power_less_imp_less_base) - -lemma power2_eq_imp_eq: - fixes x y :: "'a::{ordered_semidom,recpower}" - shows "\x\ = y\; 0 \ x; 0 \ y\ \ 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 \ (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 \ a ^ Suc(2*n) ==> 0 \ (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\0"} and @{term "0\n"}.*} - -lemma eq_number_of_0 [simp]: - "number_of v = (0::nat) \ v \ 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 \ v \ Int.Pls" -by (rule trans [OF eq_sym_conv eq_number_of_0]) - -lemma less_0_number_of [simp]: - "(0::nat) < number_of v \ 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 \ 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 \ (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 (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 \ (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 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Nat_Numeral.thy --- /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 \ 'a" ("(_\)" [1000] 999) where + "x\ \ x ^ 2" + +notation (latex output) + power2 ("(_\)" [1000] 999) + +notation (HTML output) + power2 ("(_\)" [1000] 999) + +end + +context monoid_mult +begin + +lemma power2_eq_square: "a\ = 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\ = 0" + by (simp add: power2_eq_square) + +lemma one_power2 [simp]: "1\ = 1" + by (simp add: power2_eq_square) + +end + +context comm_ring_1 +begin + +lemma power2_minus [simp]: + "(- a)\ = a\" + 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 \ x * x + y * y" + by (intro add_nonneg_nonneg zero_le_square) + +lemma not_sum_squares_lt_zero: + "\ 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 \ x = 0 \ y = 0" + by (simp add: add_nonneg_eq_0_iff) + +lemma sum_squares_le_zero_iff: + "x * x + y * y \ 0 \ x = 0 \ 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 \ x \ 0 \ y \ 0" +proof - + have "x * x + y * y \ 0 \ x \ 0 \ y \ 0" + by (simp add: sum_squares_eq_zero_iff) + then have "0 \ x * x + y * y \ x \ 0 \ y \ 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\ \ y\ \ 0 \ y \ x \ y" + unfolding numeral_2_eq_2 by (rule power_le_imp_le_base) + +lemma power2_less_imp_less: + "x\ < y\ \ 0 \ y \ x < y" + by (rule power_less_imp_less_base) + +lemma power2_eq_imp_eq: + "x\ = y\ \ 0 \ x \ 0 \ y \ 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\ = 0 \ a = 0" + by (force simp add: power2_eq_square) + +lemma zero_le_power2 [simp]: + "0 \ a\" + by (simp add: power2_eq_square) + +lemma zero_less_power2 [simp]: + "0 < a\ \ a \ 0" + by (force simp add: power2_eq_square zero_less_mult_iff linorder_neq_iff) + +lemma power2_less_0 [simp]: + "\ a\ < 0" + by (force simp add: power2_eq_square mult_less_0_iff) + +lemma abs_power2 [simp]: + "abs (a\) = a\" + by (simp add: power2_eq_square abs_mult abs_mult_self) + +lemma power2_abs [simp]: + "(abs a)\ = a\" + by (simp add: power2_eq_square abs_mult_self) + +lemma odd_power_less_zero: + "a < 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: Suc mult_less_0_iff mult_neg_neg) +qed + +lemma odd_0_le_power_imp_0_le: + "0 \ a ^ Suc (2*n) \ 0 \ a" + using odd_power_less_zero [of a n] + by (force simp add: linorder_not_less [symmetric]) + +lemma zero_le_even_power'[simp]: + "0 \ 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 \ x\ + y\" + unfolding power2_eq_square by (rule sum_squares_ge_zero) + +lemma not_sum_power2_lt_zero: + "\ x\ + y\ < 0" + unfolding power2_eq_square by (rule not_sum_squares_lt_zero) + +lemma sum_power2_eq_zero_iff: + "x\ + y\ = 0 \ x = 0 \ y = 0" + unfolding power2_eq_square by (rule sum_squares_eq_zero_iff) + +lemma sum_power2_le_zero_iff: + "x\ + y\ \ 0 \ x = 0 \ y = 0" + unfolding power2_eq_square by (rule sum_squares_le_zero_iff) + +lemma sum_power2_gt_zero_iff: + "0 < x\ + y\ \ x \ 0 \ y \ 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)\ = x\ + y\ + 2 * x * y" + by (simp add: ring_distribs power2_eq_square) + +lemma power2_diff: + fixes x y :: "'a::number_ring" + shows "(x - y)\ = x\ + y\ - 2 * x * y" + by (simp add: ring_distribs power2_eq_square) + + +subsection {* Predicate for negative binary numbers *} + +definition neg :: "int \ bool" where + "neg Z \ 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 \ 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 \ 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) \ 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' \ + (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) \ number_of v' \ + (if v \ v' then True else v \ 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\0"} and @{term "0\n"}.*} + +lemma eq_number_of_0 [simp]: + "number_of v = (0::nat) \ v \ 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 \ v \ Int.Pls" +by (rule trans [OF eq_sym_conv eq_number_of_0]) + +lemma less_0_number_of [simp]: + "(0::nat) < number_of v \ 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 \ 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 \ (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 (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 \ (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 + {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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Nominal/Examples/Fsub.thy --- 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 \ 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 \ T" and "X \ P" shows "X \ T[Y \ P]\<^sub>\" @@ -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\T'" shows "X\T[X \ T']\<^sub>\" using assms @@ -458,18 +458,19 @@ | "(VarB X U)[Y \ T]\<^sub>b = VarB X (U[Y \ T]\<^sub>\)" by auto -lemma binding_subst_fresh[fresh]: +lemma binding_subst_fresh: fixes X::"tyvrs" assumes "X \ a" and "X \ P" shows "X \ a[Y \ 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 \ B \ B[X \ U]\<^sub>b = B" - by (induct B rule: binding.induct) - (simp_all add: fresh_atm type_subst_identity) +lemma binding_subst_identity: + shows "X \ B \ B[X \ U]\<^sub>b = B" +by (induct B rule: binding.induct) + (simp_all add: fresh_atm type_subst_identity) consts subst_tyc :: "env \ tyvrs \ ty \ env" ("_[_ \ _]\<^sub>e" [100,100,100] 100) @@ -478,14 +479,14 @@ "([])[Y \ T]\<^sub>e= []" "(B#\)[Y \ T]\<^sub>e = (B[Y \ T]\<^sub>b)#(\[Y \ T]\<^sub>e)" -lemma ctxt_subst_fresh'[fresh]: +lemma ctxt_subst_fresh': fixes X::"tyvrs" assumes "X \ \" and "X \ P" shows "X \ \[Y \ P]\<^sub>e" using assms by (induct \) - (auto simp add: fresh_list_cons freshs) + (auto simp add: fresh_list_cons binding_subst_fresh) lemma ctxt_subst_mem_TVarB: "TVarB X T \ set \ \ TVarB X (T[Y \ U]\<^sub>\) \ set (\[Y \ U]\<^sub>e)" by (induct \) 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: "\ \ ok" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Nominal/Nominal.thy --- 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 \ 'x) list" -(* polymorphic operations for permutation and swapping *) +(* polymorphic constants for permutation and swapping *) consts perm :: "'x prm \ 'a \ 'a" (infixr "\" 80) swap :: "('x \ 'x) \ 'x \ '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 \ pi\x" -(* permutation on functions *) -defs (unchecked overloaded) - perm_fun_def: "pi\(f::'a\'b) \ (\x. pi\f((rev pi)\x))" - -(* permutation on bools *) -primrec (unchecked perm_bool) - true_eqvt: "pi\True = True" - false_eqvt: "pi\False = False" - +(* overloaded permutation operations *) +overloading + perm_fun \ "perm :: 'x prm \ ('a\'b) \ ('a\'b)" (unchecked) + perm_bool \ "perm :: 'x prm \ bool \ bool" (unchecked) + perm_unit \ "perm :: 'x prm \ unit \ unit" (unchecked) + perm_prod \ "perm :: 'x prm \ ('a\'b) \ ('a\'b)" (unchecked) + perm_list \ "perm :: 'x prm \ 'a list \ 'a list" (unchecked) + perm_option \ "perm :: 'x prm \ 'a option \ 'a option" (unchecked) + perm_char \ "perm :: 'x prm \ char \ char" (unchecked) + perm_nat \ "perm :: 'x prm \ nat \ nat" (unchecked) + perm_int \ "perm :: 'x prm \ int \ int" (unchecked) + + perm_noption \ "perm :: 'x prm \ 'a noption \ 'a noption" (unchecked) + perm_nprod \ "perm :: 'x prm \ ('a, 'b) nprod \ ('a, 'b) nprod" (unchecked) +begin + +definition + perm_fun_def: "perm_fun pi (f::'a\'b) \ (\x. pi\f((rev pi)\x))" + +fun + perm_bool :: "'x prm \ bool \ bool" +where + true_eqvt: "perm_bool pi True = True" +| false_eqvt: "perm_bool pi False = False" + +fun + perm_unit :: "'x prm \ unit \ unit" +where + "perm_unit pi () = ()" + +fun + perm_prod :: "'x prm \ ('a\'b) \ ('a\'b)" +where + "perm_prod pi (x,y) = (pi\x,pi\y)" + +fun + perm_list :: "'x prm \ 'a list \ 'a list" +where + nil_eqvt: "perm_list pi [] = []" +| cons_eqvt: "perm_list pi (x#xs) = (pi\x)#(pi\xs)" + +fun + perm_option :: "'x prm \ 'a option \ 'a option" +where + some_eqvt: "perm_option pi (Some x) = Some (pi\x)" +| none_eqvt: "perm_option pi None = None" + +definition + perm_char :: "'x prm \ char \ char" +where + perm_char_def: "perm_char pi c \ c" + +definition + perm_nat :: "'x prm \ nat \ nat" +where + perm_nat_def: "perm_nat pi i \ i" + +definition + perm_int :: "'x prm \ int \ int" +where + perm_int_def: "perm_int pi i \ i" + +fun + perm_noption :: "'x prm \ 'a noption \ 'a noption" +where + nsome_eqvt: "perm_noption pi (nSome x) = nSome (pi\x)" +| nnone_eqvt: "perm_noption pi nNone = nNone" + +fun + perm_nprod :: "'x prm \ ('a, 'b) nprod \ ('a, 'b) nprod" +where + "perm_nprod pi (nPair x y) = nPair (pi\x) (pi\y)" +end + + +(* permutations on booleans *) lemma perm_bool: shows "pi\(b::bool) = b" by (cases b) auto @@ -54,8 +127,7 @@ lemma if_eqvt: fixes pi::"'a prm" shows "pi\(if b then c1 else c2) = (if (pi\b) then (pi\c1) else (pi\c2))" -apply(simp add: perm_fun_def) -done + by (simp add: perm_fun_def) lemma imp_eqvt: shows "pi\(A\B) = ((pi\A)\(pi\B))" @@ -82,13 +154,7 @@ shows "(pi\(X\Y)) = (pi\X) \ (pi\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\() = ()" - -primrec (unchecked perm_prod) - "pi\(x,y) = (pi\x,pi\y)" - +(* permutations on products *) lemma fst_eqvt: "pi\(fst x) = fst (pi\x)" by (cases x) simp @@ -98,10 +164,6 @@ by (cases x) simp (* permutation on lists *) -primrec (unchecked perm_list) - nil_eqvt: "pi\[] = []" - cons_eqvt: "pi\(x#xs) = (pi\x)#(pi\xs)" - lemma append_eqvt: fixes pi :: "'x prm" and l1 :: "'a list" @@ -115,41 +177,12 @@ shows "pi\(rev l) = rev (pi\l)" by (induct l) (simp_all add: append_eqvt) -(* permutation on options *) - -primrec (unchecked perm_option) - some_eqvt: "pi\Some(x) = Some(pi\x)" - none_eqvt: "pi\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\nSome(x) = nSome(pi\x)" - nNone_eqvt: "pi\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\(nPair x1 x2) = nPair (pi\x1) (pi\x2)" - -(* permutation on characters (used in strings) *) -defs (unchecked overloaded) - perm_char_def: "pi\(c::char) \ c" - +(* permutation on characters and strings *) lemma perm_string: fixes s::"string" shows "pi\s = s" -by (induct s)(auto simp add: perm_char_def) - -(* permutation on ints *) -defs (unchecked overloaded) - perm_int_def: "pi\(i::int) \ i" - -(* permutation on nats *) -defs (unchecked overloaded) - perm_nat_def: "pi\(i::nat) \ i" + by (induct s)(auto simp add: perm_char_def) + section {* permutation equality *} (*==============================*) @@ -170,11 +203,12 @@ supports :: "'x set \ 'a \ bool" (infixl "supports" 80) "S supports x \ \a b. (a\S \ b\S \ [(a,b)]\x=x)" +(* lemmas about supp *) lemma supp_fresh_iff: fixes x :: "'a" shows "(supp x) = {a::'x. \a\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)\(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)\(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\{}" 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\() \ PROP C) \ 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 \ 'a \ bool" ("_ \* _" [100,100] 100) - -defs (overloaded) - fresh_star_set: "xs\*c \ \x\xs. x\c" - -defs (overloaded) - fresh_star_list: "xs\*c \ \x\set xs. x\c" - -lemmas fresh_star_def = fresh_star_list fresh_star_set - -lemma fresh_star_prod_set: - fixes xs::"'a set" - shows "xs\*(a,b) = (xs\*a \ xs\*b)" -by (auto simp add: fresh_star_def fresh_prod) - -lemma fresh_star_prod_list: - fixes xs::"'a list" - shows "xs\*(a,b) = (xs\*a \ xs\*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 \* c = xs \* c" - by (simp add: fresh_star_def) - -lemma fresh_star_Un_elim: - "((S \ T) \* c \ PROP C) \ (S \* c \ T \* c \ 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 \* c \ PROP C) \ (x \ c \ S \* c \ PROP C)" - by rule (simp_all add: fresh_star_def) - -lemma fresh_star_empty_elim: - "({} \* c \ PROP C) \ 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)\*() \ PROP C) \ PROP C" - and "((b::'a list)\*() \ PROP C) \ PROP C" - by (simp_all add: fresh_star_def fresh_def supp_unit) - -lemma fresh_star_prod_elim: - shows "((a::'a set)\*(x,y) \ PROP C) \ (a\*x \ a\*y \ PROP C)" - and "((b::'a list)\*(x,y) \ PROP C) \ (b\*x \ b\*y \ 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 \ pi2 \ (rev pi1) \ (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)) \ finite (S::'a set) \ \x. x \ S" - apply (drule Diff_infinite_finite) - apply (simp add: at_def) - apply blast - apply (subgoal_tac "UNIV - S \ {}") - 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 "\x. x \ 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 \ {}") + 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\(x=y) = (pi\x = pi\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\x = pi\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\x = pi\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\a)\*(pi\x) = a\*x" - and "(pi\b)\*(pi\x) = b\*x" -apply(unfold fresh_star_def) -apply(auto) -apply(drule_tac x="pi\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)\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\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)\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\a)\*(pi\x) = a\*x" - and "(pi\b)\*(pi\x) = b\*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\(a\*x) = (pi\a)\*(pi\x)" - and "pi\(b\*x) = (pi\b)\*(pi\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\(a\*x) = (pi\a)\*(pi\x)" - and "pi\(b\*x) = (pi\b)\*(pi\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) \ Xs \ Ys" - and Xs: "Xs \* (x::'a)" - and Ys: "Ys \* x" - shows "pi \ 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 \ x" "b \ 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 \ X) = (x \ X)" by (simp add: at_fin_set_supp fresh_def at fs) + section {* Permutations acting on Functions *} (*==========================================*) @@ -2540,9 +2407,8 @@ and a1: "a\x" and a2: "a\X" shows "a\(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\(set xs) = a\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 \ 'a \ bool" ("_ \* _" [100,100] 100) + +defs (overloaded) + fresh_star_set: "xs\*c \ \x\xs. x\c" + +defs (overloaded) + fresh_star_list: "xs\*c \ \x\set xs. x\c" + +lemmas fresh_star_def = fresh_star_list fresh_star_set + +lemma fresh_star_prod_set: + fixes xs::"'a set" + shows "xs\*(a,b) = (xs\*a \ xs\*b)" +by (auto simp add: fresh_star_def fresh_prod) + +lemma fresh_star_prod_list: + fixes xs::"'a list" + shows "xs\*(a,b) = (xs\*a \ xs\*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 \* c = xs \* c" + by (simp add: fresh_star_def) + +lemma fresh_star_Un_elim: + "((S \ T) \* c \ PROP C) \ (S \* c \ T \* c \ 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 \* c \ PROP C) \ (x \ c \ S \* c \ PROP C)" + by rule (simp_all add: fresh_star_def) + +lemma fresh_star_empty_elim: + "({} \* c \ PROP C) \ 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)\*() \ PROP C) \ PROP C" + and "((b::'a list)\*() \ PROP C) \ PROP C" + by (simp_all add: fresh_star_def fresh_def supp_unit) + +lemma fresh_star_prod_elim: + shows "((a::'a set)\*(x,y) \ PROP C) \ (a\*x \ a\*y \ PROP C)" + and "((b::'a list)\*(x,y) \ PROP C) \ (b\*x \ b\*y \ 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\a)\*(pi\x) = a\*x" + and "(pi\b)\*(pi\x) = b\*x" +apply(unfold fresh_star_def) +apply(auto) +apply(drule_tac x="pi\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)\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\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)\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\a)\*(pi\x) = a\*x" + and "(pi\b)\*(pi\x) = b\*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\(a\*x) = (pi\a)\*(pi\x)" + and "pi\(b\*x) = (pi\b)\*(pi\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\(a\*x) = (pi\a)\*(pi\x)" + and "pi\(b\*x) = (pi\b)\*(pi\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) \ Xs \ Ys" + and Xs: "Xs \* (x::'a)" + and Ys: "Ys \* x" + shows "pi\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 \ x" "b \ 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)\* pi" + shows "pi\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)\x = ([(a,b)]@pi)\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 \ type \ type" ("\_\_" [1000,1000] 1000) - section {* lemmas for deciding permutation equations *} (*===================================================*) @@ -3526,8 +3568,8 @@ shows "pi\(x div y) = (pi\x) div (pi\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" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Nominal/nominal_atoms.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Nominal/nominal_thmdecls.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/NthRoot.thy --- 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 \ 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)\ = x\ + y\ + 2 * x * y" -by (simp add: ring_distribs power2_eq_square) - -lemma power2_diff: - fixes x y :: "'a::{number_ring,recpower}" - shows "(x - y)\ = x\ + y\ - 2 * x * y" -by (simp add: ring_distribs power2_eq_square) - lemma real_sqrt_sum_squares_triangle_ineq: "sqrt ((a + c)\ + (b + d)\) \ sqrt (a\ + b\) + sqrt (c\ + d\)" apply (rule power2_le_imp_le, simp) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Option.thy --- 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/OrderedGroup.thy diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Orderings.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Parity.thy --- 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 "\x\ \ \y\" shows "x^n \ y^n" proof - @@ -292,7 +292,7 @@ lemma odd_pos: "odd (n::nat) \ 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 \ y" shows "x^n \ y^n" proof (cases "y < 0") @@ -406,11 +406,11 @@ subsection {* An Equivalence for @{term [source] "0 \ a^n"} *} lemma even_power_le_0_imp_0: - "a ^ (2*k) \ (0::'a::{ordered_idom,recpower}) ==> a=0" + "a ^ (2*k) \ (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 \ a^n) = (0 \ (a::'a::{ordered_idom,recpower}) | even n)" + "(0 \ a^n) = (0 \ (a::'a::{ordered_idom}) | even n)" proof cases assume even: "even n" then obtain k where "n = 2*k" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Power.thy --- 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 \ nat \ 'a" (infixr "^" 80) +subsection {* Powers for Arbitrary Monoids *} + +class power = one + times +begin -subsection{*Powers for Arbitrary Monoids*} +primrec power :: "'a \ nat \ '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 \ n" shows "a ^ m dvd a ^ n" +proof + have "a ^ n = a ^ (m + (n - m))" + using `m \ n` by simp + also have "\ = 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 \ m \ n \ a ^ m dvd b" + by (rule dvd_trans [OF le_imp_power_dvd]) + +lemma dvd_power_same: + "x dvd y \ x ^ n dvd y ^ n" + by (induct n) (auto simp add: mult_dvd_mono) + +lemma dvd_power_le: + "x dvd y \ m \ n \ x ^ n dvd y ^ m" + by (rule power_le_dvd [OF dvd_power_same]) -lemma zero_le_power[simp]: - "0 \ (a::'a::{ordered_semidom,recpower}) ==> 0 \ a^n" -by (induct n) (simp_all add: mult_nonneg_nonneg) +lemma dvd_power [simp]: + assumes "n > (0::nat) \ 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 \ 0 < a ^ n" + by (induct n) (simp_all add: mult_pos_pos) + +lemma zero_le_power [simp]: + "0 \ a \ 0 \ a ^ n" + by (induct n) (simp_all add: mult_nonneg_nonneg) lemma one_le_power[simp]: - "1 \ (a::'a::{ordered_semidom,recpower}) ==> 1 \ 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 \ (a::'a::ordered_semidom)" - by (simp add: order_trans [OF zero_le_one order_less_imp_le]) + "1 \ a \ 1 \ 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 "\ \ a * a^n" using gt1 - by (simp only: mult_mono gt1_imp_ge0 one_le_power order_less_imp_le + from gt1 have "0 \ a" + by (fact order_trans [OF zero_le_one less_imp_le]) + have "1 * 1 < a * 1" using gt1 by simp + also have "\ \ a * a ^ n" using gt1 + by (simp only: mult_mono `0 \ a` one_le_power order_less_imp_le zero_le_one order_refl) finally show ?thesis by simp qed -lemma one_less_power[simp]: - "\1 < (a::'a::{ordered_semidom,recpower}); 0 < n\ \ 1 < a ^ n" -by (cases n, simp_all add: power_gt1_lemma) +lemma power_gt1: + "1 < a \ 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 \ 0 < n \ 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 \ a^n ==> m \ n" -proof (induct m) + assumes gt1: "1 < a" + shows "a ^ m \ a ^ n \ m \ 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 \ 1" by simp + with Suc.prems Suc.hyps have "a * a ^ m \ 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^m = a^n) = (m=n)" + "1 < a \ a ^ m = a ^ n \ m = n" by (force simp add: order_antisym power_le_imp_le_exp) text{*Can relax the first premise to @{term "0 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 \ a ^ m < a ^ n \ 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 \ b; (0::'a::{recpower,ordered_semidom}) \ a|] ==> a^n \ b^n" -apply (induct "n") -apply simp_all -apply (auto intro: mult_mono order_trans [of 0 a b]) -done + "a \ b \ 0 \ a \ a ^ n \ 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}) \ 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) \ - (a = (0::'a::{mult_zero,zero_neq_one,no_zero_divisors,recpower}) & n\0)" -apply (induct "n") -apply (auto simp add: no_zero_divisors) -done - - -lemma field_power_not_zero: - "a \ (0::'a::{ring_1_no_zero_divisors,recpower}) ==> a^n \ 0" -by force - -lemma nonzero_power_inverse: - fixes a :: "'a::{division_ring,recpower}" - shows "a \ 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 \ 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 \ (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}) \ (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 \ 0 \ a \ 0 < n \ 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 \ a < 1 \ 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 \ 0 < a \ a < 1 \ 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 \ N; 0 \ a; a \ (1::'a::{ordered_semidom,recpower})|] - ==> a^N \ 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 \ 1 * a^n", simp) -apply (rule mult_mono) -apply auto -done +lemma power_decreasing [rule_format]: + "n \ N \ 0 \ a \ a \ 1 \ 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: le_Suc_eq) + apply (subgoal_tac "a * a^N \ 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 \ a < 1 \ 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 \ N; (1::'a::{ordered_semidom,recpower}) \ a|] ==> a^n \ 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 \ 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 \ N \ 1 \ a \ 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: le_Suc_eq) + apply (subgoal_tac "1 * a^n \ 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 \ 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 \ 1 < a \ 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 \ b ^ y) = (x \ y)" -by (blast intro: power_le_imp_le_exp power_increasing order_less_imp_le) + "1 < b \ b ^ x \ b ^ y \ x \ 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 \ b ^ x < b ^ y \ x < y" by (blast intro: power_less_imp_less_exp power_strict_increasing) lemma power_le_imp_le_base: -assumes le: "a ^ Suc n \ b ^ Suc n" - and ynonneg: "(0::'a::{ordered_semidom,recpower}) \ b" -shows "a \ b" + assumes le: "a ^ Suc n \ b ^ Suc n" + and ynonneg: "0 \ b" + shows "a \ b" proof (rule ccontr) assume "~ a \ 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 \ b" shows "a < b" @@ -310,98 +310,140 @@ assume "~ a < b" hence "b \ a" by (simp only: linorder_not_less) hence "b ^ n \ a ^ n" using nonneg by (rule power_mono) - thus "~ a ^ n < b ^ n" by (simp only: linorder_not_less) + thus "\ a ^ n < b ^ n" by (simp only: linorder_not_less) qed lemma power_inject_base: - "[| a ^ Suc n = b ^ Suc n; 0 \ a; 0 \ 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 \ 0 \ a \ 0 \ b \ 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 "\a ^ n = b ^ n; 0 \ a; 0 \ b; 0 < n\ \ a = b" -by (cases n, simp_all del: power_Suc, rule power_inject_base) + "a ^ n = b ^ n \ 0 \ a \ 0 \ b \ 0 < n \ 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 \ n" shows "a^m dvd a^n" -proof - have "a^n = a^(m + (n - m))" - using `m \ n` by simp - also have "\ = 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 \ a \ 0 \ 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 \ m \ n \ a^m dvd b" - by (rule dvd_trans [OF le_imp_power_dvd]) +lemma zero_le_power_abs [simp]: + "0 \ 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 \ 0 \ a ^ n \ 0" + by (induct n) auto + +end +context division_ring +begin -lemma dvd_power_same: - "(x::'a::{comm_semiring_1,recpower}) dvd y \ 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 \ 0 \ 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 \ 0 \ (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 \ m >= n \ 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 \ + a = (0::'a::{mult_zero,zero_neq_one,no_zero_divisors,power}) \ n \ 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 \ 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 \ 0" + shows "n \ m \ 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\nat)" - | "p ^ (Suc n) = (p\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 \ i \ Suc 0 \ 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 \ i ==> Suc 0 \ 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 \ x > (0::nat) \ 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 \ m = 0 \ 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"0nat)" - 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Predicate.thy --- 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 \ 'a \ bool" where "eq x x" lemma eq_is_eq: "eq x y \ (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 "\" 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Product_Type.thy --- 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Rational.thy --- 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 "\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\rat)" -| "q ^ Suc n = (q\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) \ 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 \ Rats \ a ^ n \ Rats" apply (auto simp add: Rats_def) apply (rule range_eqI) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/RealPow.thy --- 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\real)" -| "r ^ Suc n = (r\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) \ 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 \ 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 "\ 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 \ x" and y: "0 \ y" - shows "(x + y = 0) = (x = 0 \ y = 0)" -proof (auto) - from y have "x + 0 \ x + y" by (rule add_left_mono) - also assume "x + y = 0" - finally have "x \ 0" by simp - thus "x = 0" using x by (rule order_antisym) -next - from x have "0 + y \ x + y" by (rule add_right_mono) - also assume "x + y = 0" - finally have "y \ 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 \ 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 \ 0) = (x = 0 \ 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 \ 0 \ y \ 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 \ x\ + y\" -unfolding power2_eq_square by (rule sum_squares_ge_zero) - -lemma not_sum_power2_lt_zero: - fixes x y :: "'a::{ordered_idom,recpower}" - shows "\ x\ + y\ < 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\ + y\ = 0) = (x = 0 \ 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\ + y\ \ 0) = (x = 0 \ 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\ + y\) = (x \ 0 \ y \ 0)" -unfolding power2_eq_square by (rule sum_squares_gt_zero_iff) - - subsection{* Squares of Reals *} lemma real_two_squares_add_zero_iff [simp]: diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/RealVector.thy --- 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 \ Reals \ a ^ n \ 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) \ norm x ^ n" proof (induct n) case 0 show "norm (x ^ 0) \ 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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Relation.thy --- 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Relation_Power.thy --- 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 \ 'b) \ nat \ 'a \ 'b" (infixr "^^" 80) overloading - relpow \ "power \ ('a \ 'a) set \ nat \ ('a \ 'a) set" (unchecked) + relpow \ "funpower \ ('a \ 'a) set \ nat \ ('a \ '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 \ ('a \ 'a) set) ^ 0 = Id" - | "(R \ ('a \ 'a) set) ^ Suc n = R O (R ^ n)" + "(R \ ('a \ 'a) set) ^^ 0 = Id" + | "(R \ ('a \ 'a) set) ^^ Suc n = R O (R ^^ n)" end overloading - funpow \ "power \ ('a \ 'a) \ nat \ 'a \ 'a" (unchecked) + funpow \ "funpower \ ('a \ 'a) \ nat \ 'a \ '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 \ 'a \ 'a) ^ 0 = id" - | "(f \ 'a \ 'a) ^ Suc n = f o (f ^ n)" + "(f \ 'a \ 'a) ^^ 0 = id" + | "(f \ 'a \ '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 \ ('a \ 'a) \ 'a \ 'a" -where - "fun_pow 0 f = id" +primrec fun_pow :: "nat \ ('a \ 'a) \ 'a \ '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 "\ = (f^n o f^1) x" by (simp only: funpow_add) - also have "\ = (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 "\ = (f ^^ n o f ^^ 1) x" by (simp only: funpow_add) + also have "\ = (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) \ R ^^ 0" + by simp + +lemma rel_pow_Suc_I: + "(x, y) \ R ^^ n \ (y, z) \ R \ (x, z) \ R ^^ Suc n" by auto lemma rel_pow_Suc_I2: - "(x, y) : R \ (y, z) : R^n \ (x,z) : R^(Suc n)" - apply (induct n arbitrary: z) - apply simp - apply fastsimp - done + "(x, y) \ R \ (y, z) \ R ^^ n \ (x, z) \ 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) \ R ^^ 0 \ (x = y \ P) \ 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) \ R ^^ Suc n \ (\y. (x, y) \ R ^^ n \ (y, z) \ R \ P) \ 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) \ R ^^ n \ (n = 0 \ x = z \ P) + \ (\y m. n = Suc m \ (x, y) \ R ^^ m \ (y, z) \ R \ P) + \ P" by (cases n) auto lemma rel_pow_Suc_D2: - "(x, z) : R^(Suc n) \ (\y. (x,y) : R & (y,z) : R^n)" + "(x, z) \ R ^^ Suc n \ (\y. (x, y) \ R \ (y, z) \ 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': - "\x y z. (x,y) : R^n & (y,z) : R --> (\w. (x,w) : R & (w,z) : R^n)" + "\x y z. (x, y) \ R ^^ n \ (y, z) \ R \ (\w. (x, w) \ R \ (w, z) \ 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) \ R ^^ n \ (n = 0 \ x = z \ P) + \ (\y m. n = Suc m \ (x, y) \ R \ (y, z) \ R ^^ m \ P) + \ 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 \ R^* \ p \ (\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 \ R ^^ n \ p \ 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 \ r^+ = (\n > 0. x \ r^n)" + "x \ r^+ = (\n > 0. x \ 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 \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Ring_and_Field.thy --- 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 \ 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 \ 0 ==> abs (inverse (a::'a::ordered_field)) = inverse (abs a)" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/SEQ.thy --- 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 \ (\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 \ (\n. x ^ n) ----> 0" apply (drule LIMSEQ_realpow_zero [OF norm_ge_zero]) apply (simp only: LIMSEQ_Zseq_iff, erule Zseq_le) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Series.thy --- 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 \ (\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 \ summable (\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 \ summable (\n. x ^ n)" proof (rule summable_comparison_test) show "\N. \n\N. norm (x ^ n) \ norm x ^ n" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/SetInterval.thy --- 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. nnat. (!!n. n \ f n) ==> finite {n. f n \ u}" by (rule_tac B="{..u}" in finite_subset, auto intro: order_trans) @@ -855,7 +871,7 @@ lemma geometric_sum: "x ~= 1 ==> (\i=0..type, 'b\monoid_mult) graph \ nat => ('a, 'b) graph" -where - "(A \ ('a, 'b) graph) ^ 0 = 1" -| "(A \ ('a, 'b) graph) ^ Suc n = A * (A ^ n)" - -definition - graph_star_def: "star (G \ ('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" "\n. a ^ (Suc n) = a * a ^ n" - by simp_all qed +instantiation graph :: (type, monoid_mult) star +begin + +definition + graph_star_def: "star (G \ ('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 = (\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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/SizeChange/Interpretation.thy --- 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: "\x. \accp R x \ \accp R (f x)" by blast - let ?s = "\i. (f ^ i) x" + let ?s = "\i. (f ^^ i) x" { fix i diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/SizeChange/Kleene_Algebras.thy --- 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 \ x \ x * star a \ 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 (\n. a * b ^ n * c)" begin diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/SizeChange/Size_Change_Termination.thy --- 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 *) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/String.thy --- /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 \ ?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 \ UNIV)" +proof (rule UNIV_eq_I) + fix x show "x \ image (split Char) (UNIV \ 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 \ nibble \ 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\message_string) = 0" + by (cases s) simp_all + +lemma [code]: "message_string_size (s\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 \ message_string \ message_string \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Sum_Type.thy --- 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 = {} \ A = {} \ B = {}" +by(auto) subsection{*The @{term Part} Primitive*} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/Qelim/presburger.ML --- 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"}] diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/atp_manager.ML --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/atp_minimal.ML --- /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 + diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/atp_wrapper.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/hologic.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/int_arith.ML --- 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 ()) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/int_factor_simprocs.ML --- 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"; -*) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/lin_arith.ML --- 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))) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/list_code.ML --- /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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/nat_numeral_simprocs.ML --- /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 \ 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)"; +*) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/nat_simprocs.ML --- 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 \ 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/numeral.ML --- 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*) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/numeral_simprocs.ML --- /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"; +*) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/rat_arith.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/real_arith.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/recfun_codegen.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/res_reconstruct.ML --- 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=] *) + 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/string_code.ML --- /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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/string_syntax.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Tools/typecopy_package.ML --- 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 = diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Transcendental.thy --- 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 \ n \ y ^ (Suc n - p) = (y ^ (n - p)) * y" proof - assume "p \ 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 "(\p=0..p=0..p=0..z\ < \x\"}.*} lemma powser_insidea: - fixes x z :: "'a::{real_normed_field,banach,recpower}" + fixes x z :: "'a::{real_normed_field,banach}" assumes 1: "summable (\n. f n * x ^ n)" assumes 2: "norm z < norm x" shows "summable (\n. norm (f n * z ^ n))" @@ -108,7 +108,7 @@ qed lemma powser_inside: - fixes f :: "nat \ 'a::{real_normed_field,banach,recpower}" shows + fixes f :: "nat \ '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 "(\p=0..p=0.. 0" shows "((z + h) ^ n - z ^ n) / h - of_nat n * z ^ (n - Suc 0) = h * (\p=0..< n - Suc 0. \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 \ 0" assumes 2: "norm z \ K" assumes 3: "norm (z + h) \ K" @@ -433,7 +433,7 @@ qed lemma lemma_termdiff4: - fixes f :: "'a::{real_normed_field,recpower} \ + fixes f :: "'a::{real_normed_field} \ 'b::real_normed_vector" assumes k: "0 < (k::real)" assumes le: "\h. \h \ 0; norm h < k\ \ norm (f h) \ K * norm h" @@ -478,7 +478,7 @@ qed lemma lemma_termdiff5: - fixes g :: "'a::{recpower,real_normed_field} \ + fixes g :: "'a::{real_normed_field} \ nat \ '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 (\n. diffs (diffs c) n * K ^ n)" assumes 2: "norm x < norm K" shows "(\h. \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 (\n. c n * K ^ n)" assumes 2: "summable (\n. (diffs c) n * K ^ n)" assumes 3: "summable (\n. (diffs (diffs c)) n * K ^ n)" @@ -822,11 +822,11 @@ subsection {* Exponential Function *} definition - exp :: "'a \ 'a::{recpower,real_normed_field,banach}" where + exp :: "'a \ 'a::{real_normed_field,banach}" where "exp x = (\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 \ \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 (\n. norm (x ^ n /\<^sub>R real (fact n)))" proof (rule summable_norm_comparison_test [OF exI, rule_format]) show "summable (\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 \ 'a::{real_normed_algebra_1,recpower}" + fixes f :: "nat \ 'a::{real_normed_algebra_1}" shows "(\n. f n * 0 ^ n) = f 0" proof - have "(\n = 0..<1. f n * 0 ^ n) = (\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 \ \x n. x ^ n /\<^sub>R real (fact n)" shows "S (x + y) n = (\i=0..n. S x i * S y (n - i))" proof (induct n) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Transitive_Closure.thy --- 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 \ ('a \ 'a) set \ ('a \ 'a) set" +begin + +primrec relpow :: "nat \ ('a \ 'a) set \ ('a \ 'a) set" where + "relpow 0 R = Id" + | "relpow (Suc n) R = R O (R ^^ n)" + +end + +lemma rel_pow_1 [simp]: + fixes R :: "('a \ 'a) set" + shows "R ^^ 1 = R" + by simp + +lemma rel_pow_0_I: + "(x, x) \ R ^^ 0" + by simp + +lemma rel_pow_Suc_I: + "(x, y) \ R ^^ n \ (y, z) \ R \ (x, z) \ R ^^ Suc n" + by auto + +lemma rel_pow_Suc_I2: + "(x, y) \ R \ (y, z) \ R ^^ n \ (x, z) \ R ^^ Suc n" + by (induct n arbitrary: z) (simp, fastsimp) + +lemma rel_pow_0_E: + "(x, y) \ R ^^ 0 \ (x = y \ P) \ P" + by simp + +lemma rel_pow_Suc_E: + "(x, z) \ R ^^ Suc n \ (\y. (x, y) \ R ^^ n \ (y, z) \ R \ P) \ 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" + by (cases n) auto + +lemma rel_pow_Suc_D2: + "(x, z) \ R ^^ Suc n \ (\y. (x, y) \ R \ (y, z) \ 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) \ R ^^ Suc n \ (\y. (x, y) \ R \ (y, z) \ R ^^ n \ P) \ P" + by (blast dest: rel_pow_Suc_D2) + +lemma rel_pow_Suc_D2': + "\x y z. (x, y) \ R ^^ n \ (y, z) \ R \ (\w. (x, w) \ R \ (w, z) \ 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 (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 \ R^*" + shows "p \ (\n. R ^^ n)" +proof (cases p) + case (Pair x y) + with assms have "(x, y) \ R^*" by simp + then have "(x, y) \ (\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 \ R ^^ n" + shows "p \ R^*" +proof (cases p) + case (Pair x y) + with assms have "(x, y) \ R ^^ n" by simp + then have "(x, y) \ 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^* = (\n. R ^^ n)" + by (blast intro: rtrancl_imp_UN_rel_pow rel_pow_imp_rtrancl) + +lemma rtrancl_power: + "p \ R^* \ (\n. p \ R ^^ n)" + by (simp add: rtrancl_is_UN_rel_pow) + +lemma trancl_power: + "p \ R^+ \ (\n > 0. p \ 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 \ R^* \ \n. p \ R ^^ n" + by (auto dest: rtrancl_imp_UN_rel_pow) + +lemma single_valued_rel_pow: + fixes R :: "('a * 'a) set" + shows "single_valued R \ 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Typerep.thy --- 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\{} itself \ typerep" + fixes typerep :: "'a itself \ typerep" begin definition typerep_of :: "'a \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/UNITY/Comp.thy --- 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 \ H == \G. F\G = H" - strict_component_def: "(F < (H::'a program)) == (F \ H & F \ H)" +definition + component_def: "F \ H <-> (\G. F\G = H)" +definition + strict_component_def: "F < (H::'a program) <-> (F \ H & F \ 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" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/UNITY/Transformers.thy --- 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 == \i \ atMost k. ((wp act)^i) B" + "wens_single_finite act B k == \i \ atMost k. (wp act ^^ i) B" wens_single :: "[('a*'a) set, 'a set] => 'a set" - "wens_single act B == \i. ((wp act)^i) B" + "wens_single act B == \i. (wp act ^^ i) B" lemma wens_single_Un_eq: "single_valued act diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Wellfounded.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Word/BinBoolList.thy --- 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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Word/BinGeneral.thy --- 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 \ f ^^ n = f \ f ^^ (n - 1)" + by (cases n) simp_all lemmas funpow_pred_simp [simp] = funpow_minus_simp [of "number_of bin", simplified nobm1, standard] diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Word/BinOperations.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Word/Num_Lemmas.thy --- 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] diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Word/TdThs.thy --- 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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Word/WordArith.thy --- 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: diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Word/WordBitwise.thy --- 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\'a\len word) ^ n) !! m \ m = n \ m < len_of TYPE('a\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" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Word/WordDefinition.thy --- 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\'a word) ^ 0 = 1" - | "(a\'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 \ word_of_int (2^len_of TYPE('a) - 1)" + "max_word \ word_of_int (2 ^ len_of TYPE('a) - 1)" consts of_bool :: "bool \ 'a::len word" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/Word/WordShift.thy --- 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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/base.ML --- 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"; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ex/Arith_Examples.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ex/BinEx.thy --- 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 \ b ==> c \ d ==> x + y < z ==> a + c \ b + d" -by (tactic "fast_arith_tac @{context} 1") +by linarith lemma "!!a::real. a < b ==> c < d ==> a - d \ b + (-c)" -by (tactic "fast_arith_tac @{context} 1") +by linarith lemma "!!a::real. a \ b ==> b + b \ c ==> a + a \ c" -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 < 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 \ i + j + k \ a \ b \ b \ c \ i \ j \ j \ k --> a + a + a \ k + k + k" by arith lemma "!!a::real. a + b + c + d \ i + j + k + l ==> a \ b ==> b \ c ==> c \ d ==> i \ j ==> j \ k ==> k \ l ==> a \ l" -by (tactic "fast_arith_tac @{context} 1") +by linarith lemma "!!a::real. a + b + c + d \ i + j + k + l ==> a \ b ==> b \ c ==> c \ d ==> i \ j ==> j \ k ==> k \ l ==> a + a + a + a \ l + l + l + l" -by (tactic "fast_arith_tac @{context} 1") +by linarith lemma "!!a::real. a + b + c + d \ i + j + k + l ==> a \ b ==> b \ c ==> c \ d ==> i \ j ==> j \ k ==> k \ l ==> a + a + a + a + a \ l + l + l + l + i" -by (tactic "fast_arith_tac @{context} 1") +by linarith lemma "!!a::real. a + b + c + d \ i + j + k + l ==> a \ b ==> b \ c ==> c \ d ==> i \ j ==> j \ k ==> k \ l ==> a + a + a + a + a + a \ l + l + l + l + i + l" -by (tactic "fast_arith_tac @{context} 1") +by linarith subsection{*Complex Arithmetic*} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ex/Commutative_Ring_Complete.thy --- 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 \ bool" + isnorm :: "('a::{comm_ring}) pol \ bool" where "isnorm (Pc c) \ True" | "isnorm (Pinj i (Pc c)) \ False" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ex/Formal_Power_Series_Examples.thy --- 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 = (\k=0..n. of_nat (n choose k) * a^k * b^(n-k))" + "((a::'a::{ring_char_0, field, division_by_zero})+b) ^ n = (\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) \ a = fps_const (a$0) * fps_binomial c" (is "?lhs \ ?rhs") proof- diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ex/Groebner_Examples.thy --- 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 \ 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) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ex/NormalForm.thy --- 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 \ 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 \ n \ n" - add2 :: "n \ n \ n" - mul :: "n \ n \ n" - mul2 :: "n \ n \ n" - exp :: "n \ n \ 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 \ n \ n" where + "add Z = id" + | "add (S m) = S o add m" + +primrec add2 :: "n \ n \ 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 \ n \ n" where + "mul Z = (%n. Z)" + | "mul (S m) = (%n. add (mul m n) n)" + +primrec mul2 :: "n \ n \ n" where + "mul2 Z n = Z" + | "mul2 (S m) n = add2 n (mul2 m n)" + +primrec exp :: "n \ n \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ex/Numeral.thy --- 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 \ num" -where +primrec inc :: "num \ 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 \ nat" -where +primrec nat_of_num :: "num \ 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 \ num" -where +primrec num_of_nat :: "nat \ 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 \ 0" +lemma nat_of_num_neq_0: "nat_of_num x \ 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 \ '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 \ m = n" +lemma of_num_eq_iff [numeral]: "of_num m = of_num n \ 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 \ n = One" -proof - - have "of_num n = of_num One \ 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 \ 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 \ n = One" - unfolding of_num_eq_one_iff [symmetric] by auto +lemma one_eq_of_num_iff [numeral]: "1 = of_num n \ 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 \ 1 \ n = One" -proof - - have "of_num n \ of_num One \ 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 \ 1 \ n \ 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 \ of_num n" -proof - - have "of_num One \ 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 \ m < n" proof - @@ -480,18 +471,10 @@ qed lemma of_num_less_one_iff [numeral]: "\ of_num n < 1" -proof - - have "\ 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 \ n \ One" -proof - - have "of_num One < of_num n \ n \ 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 \ One < n" + using of_num_less_iff [of One n] by (simp add: of_num_One) lemma of_num_nonneg [numeral]: "0 \ 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 \ 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) \ 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 \ a * b = b * a" + +lemma commutes_with_commute: "commutes_with a b \ a * b = b * a" +unfolding commutes_with_def . + +lemma commutes_with_left_commute: "commutes_with a b \ 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 \ #4 * #2 + #7 = (#8 :: nat) \ #4 * #2 + #7 \ (#8 :: int) - #3" code_thms bar diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ex/Predicate_Compile.thy --- 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 \ ('a \ 'a Predicate.pred) option) - \ 'a Predicate.seq \ ('a \ '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 \ next yield xq | Some (x, Q) \ Some (x, Predicate.Seq (\_. Predicate.Join Q xq)))" + +text {* Experimental code *} + +definition pred_map :: "('a \ 'b) \ 'a Predicate.pred \ '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 "\ :: '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 \ ('a \ 'b) option) \ index \ 'b \ 'a list \ 'b" where - "anamorph f k x = (if k = 0 then ([], x) - else case f x of None \ ([], x) | Some (v, y) \ let (vs, z) = anamorph f (k - 1) y in (v # vs, z))" + +text {* Example(s) *} + +inductive even :: "nat \ bool" and odd :: "nat \ bool" where + "even 0" + | "even n \ odd (Suc n)" + | "odd n \ even (Suc n)" + +setup {* pred_compile "even" *} +thm even_codegen + + +inductive append :: "'a list \ 'a list \ 'a list \ bool" where + append_Nil: "append [] xs xs" + | append_Cons: "append xs ys zs \ 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 "\ :: 'a Predicate.pred"} (*replace bottom with sequence to evaluate*) -end -*} +setup {* pred_compile "append" *} +thm append_codegen + + +inductive partition :: "('a \ bool) \ 'a list \ 'a list \ 'a list \ bool" + for f where + "partition f [] [] []" + | "f x \ partition f xs ys zs \ partition f (x # xs) (x # ys) zs" + | "\ f x \ partition f xs ys zs \ 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ex/Quickcheck_Generators.thy --- 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 \ '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 \ typerep \ ('a \ 'a \ bool) \ ('a \ term) - \ (seed \ ('b \ (unit \ term)) \ seed) \ (seed \ seed \ seed) - \ seed \ (('a \ 'b) \ (unit \ term)) \ seed" - -code_const random_fun_aux (SML "Random'_Engine.random'_fun") - -instantiation "fun" :: ("{eq, term_of}", "{type, random}") random -begin - -definition random_fun :: "index \ seed \ (('a \ 'b) \ (unit \ term)) \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ex/ReflectionEx.thy --- 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 \ ('a::{ordered_idom,recpower}) list \'a" +consts Iprod :: " prod \ ('a::{ordered_idom}) list \'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 \ ('a::{ordered_idom, recpower}) list \bool" +consts Isgn :: " sgn \ ('a::{ordered_idom}) list \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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOL/ex/predicate_compile.ML --- 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' diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Adm.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 @@ "\chain (Y::nat \ 'a::cpo); \i. \j\i. P (Y j)\ \ (\i. Y i) = (\i. Y (LEAST j. i \ j \ 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: "\cont u; cont v\ \ adm (\x. u x \ v x)" +lemma adm_below: "\cont u; cont v\ \ adm (\x. u x \ v x)" apply (rule admI) apply (simp add: cont2contlubE) apply (rule lub_mono) @@ -132,7 +132,7 @@ done lemma adm_eq: "\cont u; cont v\ \ adm (\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: "\cont t; adm P\ \ adm (\x. P (t x))" apply (rule admI) @@ -142,11 +142,11 @@ apply (erule spec) done -lemma adm_not_less: "cont t \ adm (\x. \ t x \ u)" +lemma adm_not_below: "cont t \ adm (\x. \ t x \ 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: "\compact k; cont t\ \ adm (\x. \ k \ t x)" +lemma adm_compact_not_below: "\compact k; cont t\ \ adm (\x. \ k \ t x)" unfolding compact_def by (rule adm_subst) lemma adm_neq_compact: "\compact k; cont t\ \ adm (\x. t x \ 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: "\compact k; cont t\ \ adm (\x. k \ 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 \" 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Algebraic.thy --- 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 \ 'a::cpo" - assumes less: "\x. f\x \ x" + assumes below: "\x. f\x \ x" assumes finite_range: "finite (range (\x. f\x))" begin -lemma iterate_less: "iterate i\f\x \ x" -by (induct i, simp_all add: trans_less [OF less]) +lemma iterate_below: "iterate i\f\x \ x" +by (induct i, simp_all add: below_trans [OF below]) lemma iterate_fixed: "f\x = x \ iterate i\f\x = x" by (induct i, simp_all) lemma antichain_iterate_app: "i \ j \ iterate j\f\x \ iterate i\f\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 (\i. iterate i\f\x))" @@ -144,7 +144,7 @@ next fix x :: 'a show "d\x \ 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\x = x}" @@ -163,7 +163,7 @@ interpret d: finite_deflation d by fact fix x show "\x. (d oo f)\x \ x" - by (simp, rule trans_less [OF d.less f]) + by (simp, rule below_trans [OF d.below f]) show "finite (range (\x. (d oo f)\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 \ '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 \ \ \x y. Rep_fin_defl x \ 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: "(\x. Rep_fin_defl a\x = x \ Rep_fin_defl b\x = x) \ a \ 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: "\a \ b; Rep_fin_defl a\x = x\ \ Rep_fin_defl b\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: "(\x. Rep_fin_defl a\x = x \ Rep_fin_defl b\x = x) \ 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: "\finite_deflation a; finite_deflation b; a \ b\ \ Abs_fin_defl a \ 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\x = x \ Rep_fin_defl d\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 \ d" -apply (rule fin_defl_lessI) +lemma fd_take_below: "fd_take n d \ d" +apply (rule fin_defl_belowI) apply (simp add: fd_take_fixed_iff) done @@ -278,16 +277,16 @@ done lemma fd_take_mono: "a \ b \ fd_take n a \ 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: "\i \ j; approx i\x = x\ \ approx j\x = x" by (erule subst, simp add: min_def) lemma fd_take_chain: "m \ n \ fd_take m a \ 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: "\n. fd_take n a = a" apply (rule_tac x= "Max ((\x. LEAST n. approx n\x = x) ` {x. Rep_fin_defl a\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 \ Rep_alg_defl (\i. Y i) = (\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 \ 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\(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\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 "(\i. ?a i) = ID" apply (rule ext_cfun, simp) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Bifinite.thy --- 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\x \ x" +lemma approx_below: "approx i\x \ x" proof - have "chain (\i. approx i\x)" by simp hence "approx i\x \ (\i. approx i\x)" by (rule is_ub_thelub) @@ -32,7 +32,7 @@ show "approx i\(approx i\x) = approx i\x" by (rule approx_idem) show "approx i\x \ x" - by (rule approx_less) + by (rule approx_below) show "finite {x. approx i\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\\ = \" -by (rule UU_I, rule approx_less) +by (rule UU_I, rule approx_below) lemma approx_approx1: "i \ j \ approx i\(approx j\x) = approx i\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 \ i \ approx i\(approx j\x) = approx j\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: "(\i. approx i\x \ approx i\y) \ x \ y" +lemma profinite_below_ext: "(\i. approx i\x \ approx i\y) \ x \ y" apply (subgoal_tac "(\i. approx i\x) \ (\i. approx i\y)", simp) apply (rule lub_mono, simp, simp, simp) done diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Cfun.thy --- 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 \ g = (\x. f\x \ g\x)" -by (simp add: less_CFun_def expand_fun_less) +lemma expand_cfun_below: "f \ g = (\x. f\x \ g\x)" +by (simp add: below_CFun_def expand_fun_below) -lemma less_cfun_ext: "(\x. f\x \ g\x) \ f \ g" -by (simp add: expand_cfun_less) +lemma below_cfun_ext: "(\x. f\x \ g\x) \ f \ 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 \ g \ f\x \ g\x" -by (simp add: expand_cfun_less) +by (simp add: expand_cfun_below) lemma monofun_cfun_arg: "x \ y \ f\x \ f\y" by (rule monofun_Rep_CFun2 [THEN monofunE]) lemma monofun_cfun: "\f \ g; x \ y\ \ f\x \ g\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]: "\\x. chain (\i. S i x); \i. cont (\x. S i x)\ \ chain (\i. \ 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: "\\x. cont (\y. f x y); \y. monofun (\x. f x y)\ \ monofun (\x. \ 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 (\p. f (fst p) (snd p))" shows "cont (\x. \ y. f x y)" proof (rule cont2cont_LAM) - fix x :: 'a - have "cont (\y. (x, y))" - by (rule cont_pair2) - with f have "cont (\y. f (fst (x, y)) (snd (x, y)))" - by (rule cont2cont_app3) - thus "cont (\y. f x y)" - by (simp only: fst_conv snd_conv) + fix x :: 'a show "cont (\y. f x y)" + using f by (rule cont_fst_snd_D2) next - fix y :: 'b - have "cont (\x. (x, y))" - by (rule cont_pair1) - with f have "cont (\x. f (fst (x, y)) (snd (x, y)))" - by (rule cont2cont_app3) - thus "cont (\x. f x y)" - by (simp only: fst_conv snd_conv) + fix y :: 'b show "cont (\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: "\cont f; cont g; f \ g\ \ Abs_CFun f \ 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: "\x. f\(g\x) = x \ (g\x \ g\y) = (x \ y)" apply (rule iffI) apply (drule_tac f=f in monofun_cfun_arg) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/CompactBasis.thy --- 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 \ 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 = (\x. {a. Rep_compact_basis a \ 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 "\x. x \ approximants w" unfolding approximants_def apply (rule_tac x="Abs_compact_basis (approx 0\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)\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 "(\i. approx i\x) \ y", simp) apply (rule admD, simp, simp) apply (drule_tac c="Abs_compact_basis (approx i\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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Completion.thy --- 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 \ 'b::sq_ord" + fixes Abs :: "'a set \ 'b::below" assumes type: "type_definition Rep Abs {S. ideal S}" - assumes less: "\x y. x \ y \ Rep x \ Rep y" + assumes below: "\x y. x \ y \ Rep x \ 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 \ 'b::po" assumes type: "type_definition Rep Abs {S. ideal S}" - assumes less: "\x y. x \ y \ Rep x \ Rep y" + assumes below: "\x y. x \ y \ Rep x \ Rep y" assumes S: "chain S" shows typedef_ideal_lub: "range S <<| Abs (\i. Rep (S i))" and typedef_ideal_rep_contlub: "Rep (\i. S i) = (\i. Rep (S i))" @@ -130,7 +130,7 @@ have 1: "ideal (\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 (\i. Rep (S i))) = (\i. Rep (S i))" @@ -138,8 +138,8 @@ show 3: "range S <<| Abs (\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: "(\i. S i) = Abs (\i. Rep (S i))" by (rule thelubI) @@ -150,16 +150,16 @@ lemma typedef_ideal_cpo: fixes Abs :: "'a set \ 'b::po" assumes type: "type_definition Rep Abs {S. ideal S}" - assumes less: "\x y. x \ y \ Rep x \ Rep y" + assumes below: "\x y. x \ y \ Rep x \ 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 \ 'a \ bool" +interpretation below: preorder "below :: 'a::po \ 'a \ 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 \ y \ rep x \ rep y" +lemma below_def: "x \ y \ rep x \ rep y" by (rule iffI [OF rep_mono subset_repD]) lemma rep_eq: "rep x = {a. principal a \ 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 \ rep x \ principal a \ x" +lemma mem_rep_iff_principal_below: "a \ rep x \ principal a \ x" by (simp add: rep_eq) -lemma principal_less_iff_mem_rep: "principal a \ x \ a \ rep x" +lemma principal_below_iff_mem_rep: "principal a \ x \ a \ rep x" by (simp add: rep_eq) -lemma principal_less_iff [simp]: "principal a \ principal b \ a \ b" -by (simp add: principal_less_iff_mem_rep rep_principal) +lemma principal_below_iff [simp]: "principal a \ principal b \ a \ b" +by (simp add: principal_below_iff_mem_rep rep_principal) lemma principal_eq_iff: "principal a = principal b \ a \ b \ b \ a" -unfolding po_eq_conv [where 'a='b] principal_less_iff .. +unfolding po_eq_conv [where 'a='b] principal_below_iff .. lemma repD: "a \ rep x \ principal a \ x" by (simp add: rep_eq) lemma principal_mono: "a \ b \ principal a \ principal b" -by (simp only: principal_less_iff) +by (simp only: principal_below_iff) -lemma lessI: "(\a. principal a \ x \ principal a \ u) \ x \ u" -unfolding principal_less_iff_mem_rep -by (simp add: less_def subset_eq) +lemma belowI: "(\a. principal a \ x \ principal a \ u) \ x \ 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: "\a b. a \ b \ f a \ f b" assumes g_mono: "\a b. a \ b \ g a \ g b" - assumes less: "\a. f a \ g a" + assumes below: "\a. f a \ g a" shows "basis_fun f \ 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Cont.thy --- 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: "\Y. \chain Y; chain (\i. f (Y i))\ + assumes below: "\Y. \chain Y; chain (\i. f (Y i))\ \ f (\i. Y i) \ (\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 \ 'b::cpo \ 'c::cpo" and t :: "'a \ 'b" - assumes f1: "\y. cont (\x. f x y)" - assumes f2: "\x. cont (\y. f x y)" - assumes t: "cont (\x. t x)" + assumes 1: "cont (\x. t x)" + assumes 2: "\x. cont (\y. f x y)" + assumes 3: "\y. cont (\x. f x y)" shows "cont (\x. (f x) (t x))" proof (rule monocontlub2cont [OF monofunI contlubI]) fix x y :: "'a" assume "x \ y" then show "f x (t x) \ 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 \ 'a" assume "chain Y" then show "f (\i. Y i) (t (\i. Y i)) = (\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: "\cont c; cont (\x. f x)\ \ cont (\x. c (f x))" -by (rule cont2cont_apply [OF cont_const]) +by (rule cont_apply [OF _ _ cont_const]) text {* if-then-else is continuous *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/ConvexPD.thy --- 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 \ Rep_convex_pd (\i. Y i) = (\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}\ \ ys +\ zs \ {x}\ \ ys \ {x}\ \ 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 +\ ys \ {z}\ \ xs \ {z}\ \ ys \ {z}\" 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}\ \ {y}\ \ x \ y" +lemma convex_unit_below_iff [simp]: "{x}\ \ {y}\ \ x \ 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\x" in compact_basis.compact_imp_principal, simp) apply (cut_tac x="approx i\y" in compact_basis.compact_imp_principal, simp) @@ -433,12 +433,12 @@ lemma monofun_LAM: "\cont f; cont g; \x. f x \ g x\ \ (\ x. f x) \ (\ x. g x)" -by (simp add: expand_cfun_less) +by (simp add: expand_cfun_below) lemma convex_bind_basis_mono: "t \\ u \ convex_bind_basis t \ 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 \ ys) = (convex_to_upper\xs \ convex_to_upper\ys \ convex_to_lower\xs \ convex_to_lower\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\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 +\ ys" and ys="zs +\ ws", standard] +lemmas convex_plus_below_plus_iff = + convex_pd_below_iff [where xs="xs +\ ys" and ys="zs +\ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Cprod.thy --- 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 = a' \ b = b')" by (simp add: cpair_eq_pair) -lemma cpair_less [iff]: "( \ ) = (a \ a' \ b \ b')" +lemma cpair_below [iff]: "( \ ) = (a \ a' \ b \ b')" by (simp add: cpair_eq_pair) lemma cpair_defined_iff [iff]: "( = \) = (x = \ \ y = \)" @@ -107,23 +107,23 @@ lemmas surjective_pairing_Cprod2 = cpair_cfst_csnd -lemma less_cprod: "x \ y = (cfst\x \ cfst\y \ csnd\x \ csnd\y)" -by (simp add: less_cprod_def cfst_def csnd_def cont_fst cont_snd) +lemma below_cprod: "x \ y = (cfst\x \ cfst\y \ csnd\x \ csnd\y)" +by (simp add: below_prod_def cfst_def csnd_def cont_fst cont_snd) lemma eq_cprod: "(x = y) = (cfst\x = cfst\y \ csnd\x = csnd\y)" -by (auto simp add: po_eq_conv less_cprod) +by (auto simp add: po_eq_conv below_cprod) -lemma cfst_less_iff: "cfst\x \ y = x \ x>" -by (simp add: less_cprod) +lemma cfst_below_iff: "cfst\x \ y = x \ x>" +by (simp add: below_cprod) -lemma csnd_less_iff: "csnd\x \ y = x \ x, y>" -by (simp add: less_cprod) +lemma csnd_below_iff: "csnd\x \ y = x \ x, y>" +by (simp add: below_cprod) lemma compact_cfst: "compact x \ compact (cfst\x)" -by (rule compactI, simp add: cfst_less_iff) +by (rule compactI, simp add: cfst_below_iff) lemma compact_csnd: "compact x \ compact (csnd\x)" -by (rule compactI, simp add: csnd_less_iff) +by (rule compactI, simp add: csnd_below_iff) lemma compact_cpair: "\compact x; compact y\ \ compact " by (simp add: cpair_eq_pair) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Deflation.thy --- 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 \ 'a" assumes idem: "\x. d\(d\x) = d\x" - assumes less: "\x. d\x \ x" + assumes below: "\x. d\x \ x" begin -lemma less_ID: "d \ ID" -by (rule less_cfun_ext, simp add: less) +lemma below_ID: "d \ 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: "\x. d\x = x \ f\x = x" shows "d \ f" -proof (rule less_cfun_ext) +proof (rule below_cfun_ext) fix x - from less have "f\(d\x) \ f\x" by (rule monofun_cfun_arg) + from below have "f\(d\x) \ f\x" by (rule monofun_cfun_arg) also from idem have "f\(d\x) = d\x" by (rule f) finally show "d\x \ f\x" . qed -lemma lessD: "\f \ d; f\x = x\ \ d\x = x" -proof (rule antisym_less) - from less show "d\x \ x" . +lemma belowD: "\f \ d; f\x = x\ \ d\x = x" +proof (rule below_antisym) + from below show "d\x \ x" . next assume "f \ d" hence "f\x \ d\x" by (rule monofun_cfun_fun) @@ -64,11 +64,11 @@ lemma deflation_UU: "deflation \" by (simp add: deflation.intro) -lemma deflation_less_iff: +lemma deflation_below_iff: "\deflation p; deflation q\ \ p \ q \ (\x. p\x = x \ q\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 \ g \ f\(g\x) = f\x" -proof (rule antisym_less) +proof (rule below_antisym) interpret g: deflation g by fact - from g.less show "f\(g\x) \ f\x" by (rule monofun_cfun_arg) + from g.below show "f\(g\x) \ f\x" by (rule monofun_cfun_arg) next interpret f: deflation f by fact assume "f \ g" hence "f\x \ g\x" by (rule monofun_cfun_fun) @@ -91,9 +91,9 @@ finally show "f\x \ f\(g\x)" . qed -lemma deflation_less_comp2: +lemma deflation_below_comp2: "\deflation f; deflation g; f \ g\ \ g\(f\x) = f\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\x \ d\(Y j)" using j by simp hence "d\x \ Y j" - using less by (rule trans_less) + using below by (rule below_trans) thus "\j. d\x \ Y j" .. qed @@ -155,10 +155,10 @@ locale ep_pair = fixes e :: "'a \ 'b" and p :: "'b \ 'a" assumes e_inverse [simp]: "\x. p\(e\x) = x" - and e_p_less: "\y. e\(p\y) \ y" + and e_p_below: "\y. e\(p\y) \ y" begin -lemma e_less_iff [simp]: "e\x \ e\y \ x \ y" +lemma e_below_iff [simp]: "e\x \ e\y \ x \ y" proof assume "e\x \ e\y" hence "p\(e\x) \ p\(e\y)" by (rule monofun_cfun_arg) @@ -169,7 +169,7 @@ qed lemma e_eq_iff [simp]: "e\x = e\y \ x = y" -unfolding po_eq_conv e_less_iff .. +unfolding po_eq_conv e_below_iff .. lemma p_eq_iff: "\e\(p\x) = x; e\(p\y) = y\ \ p\x = p\y \ x = y" @@ -178,7 +178,7 @@ lemma p_inverse: "(\x. y = e\x) = (e\(p\y) = y)" by (auto, rule exI, erule sym) -lemma e_less_iff_less_p: "e\x \ y \ x \ p\y" +lemma e_below_iff_below_p: "e\x \ y \ x \ p\y" proof assume "e\x \ y" then have "p\(e\x) \ p\y" by (rule monofun_cfun_arg) @@ -186,7 +186,7 @@ next assume "x \ p\y" then have "e\x \ e\(p\y)" by (rule monofun_cfun_arg) - then show "e\x \ y" using e_p_less by (rule trans_less) + then show "e\x \ y" using e_p_below by (rule below_trans) qed lemma compact_e_rev: "compact (e\x) \ compact x" @@ -203,7 +203,7 @@ assume "compact x" hence "adm (\y. \ x \ y)" by (rule compactD) hence "adm (\y. \ x \ p\y)" by (rule adm_subst [OF cont_Rep_CFun2]) - hence "adm (\y. \ e\x \ y)" by (simp add: e_less_iff_less_p) + hence "adm (\y. \ e\x \ y)" by (simp add: e_below_iff_below_p) thus "compact (e\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)\((e oo d oo p)\x) = (e oo d oo p)\x" by (simp add: idem) show "(e oo d oo p)\x \ 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)\((e oo d oo p)\x) = (e oo d oo p)\x" by (simp add: idem) show "(e oo d oo p)\x \ x" - by (simp add: e_less_iff_less_p less) + by (simp add: e_below_iff_below_p below) have "finite ((\x. e\x) ` (\x. d\x) ` range (\x. p\x))" by (simp add: finite_image) hence "finite (range (\x. (e oo d oo p)\x))" @@ -254,24 +254,24 @@ { fix x have "d\(e\x) \ e\x" - by (rule d.less) + by (rule d.below) hence "p\(d\(e\x)) \ p\(e\x)" by (rule monofun_cfun_arg) hence "(p oo d oo e)\x \ 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)\x \ x" - by (rule p_d_e_less) + by (rule p_d_e_below) next fix x show "(p oo d oo e)\((p oo d oo e)\x) = (p oo d oo e)\x" - proof (rule antisym_less) + proof (rule below_antisym) show "(p oo d oo e)\((p oo d oo e)\x) \ (p oo d oo e)\x" - by (rule p_d_e_less) + by (rule p_d_e_below) have "p\(d\(d\(d\(e\x)))) \ p\(d\(e\(p\(d\(e\x)))))" by (intro monofun_cfun_arg d) hence "p\(d\(e\x)) \ p\(d\(e\(p\(d\(e\x)))))" @@ -315,29 +315,29 @@ lemma ep_pair_unique_e_lemma: assumes "ep_pair e1 p" and "ep_pair e2 p" shows "e1 \ 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\(p\(e2\x)) \ e2\x" - by (rule e1.e_p_less) + by (rule e1.e_p_below) thus "e1\x \ e2\x" by (simp only: e2.e_inverse) qed lemma ep_pair_unique_e: "\ep_pair e1 p; ep_pair e2 p\ \ 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 \ 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\(p1\x) \ x" - by (rule p1.e_p_less) + by (rule p1.e_p_below) hence "p2\(e\(p1\x)) \ p2\x" by (rule monofun_cfun_arg) thus "p1\x \ p2\x" @@ -346,7 +346,7 @@ lemma ep_pair_unique_p: "\ep_pair e p1; ep_pair e p2\ \ 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)\((e2 oo e1)\x) = x" by simp have "e1\(p1\(p2\y)) \ p2\y" - by (rule ep1.e_p_less) + by (rule ep1.e_p_below) hence "e2\(e1\(p1\(p2\y))) \ e2\(p2\y)" by (rule monofun_cfun_arg) also have "e2\(p2\y) \ y" - by (rule ep2.e_p_less) + by (rule ep2.e_p_below) finally show "(e2 oo e1)\((p1 oo p2)\y) \ y" by simp qed @@ -381,7 +381,7 @@ proof - have "\ \ p\\" by (rule minimal) hence "e\\ \ e\(p\\)" by (rule monofun_cfun_arg) - also have "e\(p\\) \ \" by (rule e_p_less) + also have "e\(p\\) \ \" by (rule e_p_below) finally show "e\\ = \" by simp qed diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Discrete.thy --- 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 \ :: 'a discr \ 'a discr \ 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Domain.thy --- 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\x \ abs\y) = (x \ y)" +lemma abs_below: "(abs\x \ abs\y) = (x \ y)" proof assume "abs\x \ abs\y" then have "rep\(abs\x) \ rep\(abs\y)" by (rule monofun_cfun_arg) @@ -35,11 +43,11 @@ then show "abs\x \ abs\y" by (rule monofun_cfun_arg) qed -lemma rep_less: "(rep\x \ rep\y) = (x \ y)" - by (rule iso.abs_less [OF swap]) +lemma rep_below: "(rep\x \ rep\y) = (x \ y)" + by (rule iso.abs_below [OF swap]) lemma abs_eq: "(abs\x = abs\y) = (x = y)" - by (simp add: po_eq_conv abs_less) + by (simp add: po_eq_conv abs_below) lemma rep_eq: "(rep\x = rep\y) = (x = y)" by (rule iso.abs_eq [OF swap]) @@ -83,7 +91,7 @@ assume "adm (\y. \ abs\x \ y)" with cont_Rep_CFun2 have "adm (\y. \ abs\x \ abs\y)" by (rule adm_subst) - then show "adm (\y. \ x \ y)" using abs_less by simp + then show "adm (\y. \ x \ y)" using abs_below by simp qed lemma compact_rep_rev: "compact (rep\x) \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/FOCUS/Stream_adm.thy --- 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? *) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Ffun.thy --- 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 \) \ (\f g. \x. f x \ g x)" + below_fun_def: "(op \) \ (\f g. \x. f x \ g x)" instance .. end @@ -23,45 +23,45 @@ proof fix f :: "'a \ 'b" show "f \ f" - by (simp add: less_fun_def) + by (simp add: below_fun_def) next fix f g :: "'a \ 'b" assume "f \ g" and "g \ 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 \ 'b" assume "f \ g" and "g \ h" thus "f \ 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 \ g) = (\x. f x \ g x)" -by (simp add: less_fun_def) +lemma expand_fun_below: "(f \ g) = (\x. f x \ g x)" +by (simp add: below_fun_def) -lemma less_fun_ext: "(\x. f x \ g x) \ f \ g" -by (simp add: less_fun_def) +lemma below_fun_ext: "(\x. f x \ g x) \ f \ g" +by (simp add: below_fun_def) subsection {* Full function space is chain complete *} text {* function application is monotone *} lemma monofun_app: "monofun (\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 \ chain (\i. S i x)" -by (simp add: chain_def less_fun_def) +by (simp add: chain_def below_fun_def) lemma ch2ch_lambda: "(\x. chain (\i. S i x)) \ 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 \ range (\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 \ 'b" show "f \ g \ 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: "(\x. \) \ f" -by (simp add: less_fun_def) +by (simp add: below_fun_def) lemma least_fun: "\x::'a::type \ 'b::pcpo. \y. x \ y" apply (rule_tac x = "\x. \" in exI) @@ -171,13 +171,13 @@ *} lemma monofun_fun_fun: "f \ g \ f x \ g x" -by (simp add: less_fun_def) +by (simp add: below_fun_def) lemma monofun_fun_arg: "\monofun f; x \ y\ \ f x \ f y" by (rule monofunE) lemma monofun_fun: "\monofun f; monofun g; f \ g; x \ y\ \ f x \ 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: "\y. monofun (\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 - diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Fix.thy --- 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\x \ x \ fix\F \ x" +lemma fix_least_below: "F\x \ x \ fix\F \ 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\x = x \ fix\F \ x" -by (rule fix_least_less, simp) +by (rule fix_least_below, simp) lemma fix_eqI: assumes fixed: "F\x = x" and least: "\z. F\z = z \ x \ z" shows "fix\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 \ y" by (rule fix_least, simp add: F_y) hence "cfst\(F\\x, ?y1\) \ cfst\(F\\x, y\)" by (simp add: monofun_cfun) hence "cfst\(F\\x, ?y1\) \ x" using F_x by simp - hence 1: "?x \ x" by (simp add: fix_least_less) + hence 1: "?x \ x" by (simp add: fix_least_below) hence "csnd\(F\\?x, y\) \ csnd\(F\\x, y\)" by (simp add: monofun_cfun) hence "csnd\(F\\?x, y\) \ y" using F_y by simp - hence 2: "?y \ y" by (simp add: fix_least_less) + hence 2: "?y \ y" by (simp add: fix_least_below) show "\?x, ?y\ \ z" using z 1 2 by simp qed diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Fixrec.thy --- 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 \ unit maybe" where - "match_UU = (\ x. fail)" + match_UU :: "'a \ 'c maybe \ 'c maybe" +where + "match_UU = strictify\(\ x k. fail)" definition - match_cpair :: "'a::cpo \ 'b::cpo \ ('a \ 'b) maybe" where - "match_cpair = csplit\(\ x y. return\)" + match_cpair :: "'a::cpo \ 'b::cpo \ ('a \ 'b \ 'c maybe) \ 'c maybe" +where + "match_cpair = (\ x k. csplit\k\x)" definition - match_spair :: "'a \ 'b \ ('a \ 'b) maybe" where - "match_spair = ssplit\(\ x y. return\)" + match_spair :: "'a \ 'b \ ('a \ 'b \ 'c maybe) \ 'c maybe" +where + "match_spair = (\ x k. ssplit\k\x)" definition - match_sinl :: "'a \ 'b \ 'a maybe" where - "match_sinl = sscase\return\(\ y. fail)" + match_sinl :: "'a \ 'b \ ('a \ 'c maybe) \ 'c maybe" +where + "match_sinl = (\ x k. sscase\k\(\ b. fail)\x)" definition - match_sinr :: "'a \ 'b \ 'b maybe" where - "match_sinr = sscase\(\ x. fail)\return" + match_sinr :: "'a \ 'b \ ('b \ 'c maybe) \ 'c maybe" +where + "match_sinr = (\ x k. sscase\(\ a. fail)\k\x)" definition - match_up :: "'a::cpo u \ 'a maybe" where - "match_up = fup\return" + match_up :: "'a::cpo u \ ('a \ 'c maybe) \ 'c maybe" +where + "match_up = (\ x k. fup\k\x)" definition - match_ONE :: "one \ unit maybe" where - "match_ONE = (\ ONE. return\())" + match_ONE :: "one \ 'c maybe \ 'c maybe" +where + "match_ONE = (\ ONE k. k)" + +definition + match_TT :: "tr \ 'c maybe \ 'c maybe" +where + "match_TT = (\ x k. If x then k else fail fi)" definition - match_TT :: "tr \ unit maybe" where - "match_TT = (\ b. If b then return\() else fail fi)" - -definition - match_FF :: "tr \ unit maybe" where - "match_FF = (\ b. If b then fail else return\() fi)" + match_FF :: "tr \ 'c maybe \ 'c maybe" +where + "match_FF = (\ x k. If x then fail else k fi)" lemma match_UU_simps [simp]: - "match_UU\x = fail" -by (simp add: match_UU_def) + "match_UU\\\k = \" + "x \ \ \ match_UU\x\k = fail" +by (simp_all add: match_UU_def) lemma match_cpair_simps [simp]: - "match_cpair\ = return\" + "match_cpair\\x, y\\k = k\x\y" by (simp add: match_cpair_def) lemma match_spair_simps [simp]: - "\x \ \; y \ \\ \ match_spair\(:x,y:) = return\" - "match_spair\\ = \" + "\x \ \; y \ \\ \ match_spair\(:x, y:)\k = k\x\y" + "match_spair\\\k = \" by (simp_all add: match_spair_def) lemma match_sinl_simps [simp]: - "x \ \ \ match_sinl\(sinl\x) = return\x" - "x \ \ \ match_sinl\(sinr\x) = fail" - "match_sinl\\ = \" + "x \ \ \ match_sinl\(sinl\x)\k = k\x" + "y \ \ \ match_sinl\(sinr\y)\k = fail" + "match_sinl\\\k = \" by (simp_all add: match_sinl_def) lemma match_sinr_simps [simp]: - "x \ \ \ match_sinr\(sinr\x) = return\x" - "x \ \ \ match_sinr\(sinl\x) = fail" - "match_sinr\\ = \" + "x \ \ \ match_sinr\(sinl\x)\k = fail" + "y \ \ \ match_sinr\(sinr\y)\k = k\y" + "match_sinr\\\k = \" by (simp_all add: match_sinr_def) lemma match_up_simps [simp]: - "match_up\(up\x) = return\x" - "match_up\\ = \" + "match_up\(up\x)\k = k\x" + "match_up\\\k = \" by (simp_all add: match_up_def) lemma match_ONE_simps [simp]: - "match_ONE\ONE = return\()" - "match_ONE\\ = \" + "match_ONE\ONE\k = k" + "match_ONE\\\k = \" by (simp_all add: match_ONE_def) lemma match_TT_simps [simp]: - "match_TT\TT = return\()" - "match_TT\FF = fail" - "match_TT\\ = \" + "match_TT\TT\k = k" + "match_TT\FF\k = fail" + "match_TT\\\k = \" by (simp_all add: match_TT_def) lemma match_FF_simps [simp]: - "match_FF\FF = return\()" - "match_FF\TT = fail" - "match_FF\\ = \" + "match_FF\FF\k = k" + "match_FF\TT\k = fail" + "match_FF\\\k = \" 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/HOLCF.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/IOA/meta_theory/Sequence.thy --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/IOA/meta_theory/ioa_package.ML --- 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]), diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/IsaMakefile --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Lift.thy --- 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: "\x = Def s; x = \\ \ R" by simp -lemma Def_inject_less_eq: "Def x \ Def y \ x = y" -by (simp add: less_lift_def Def_def Abs_lift_inverse lift_def) +lemma Def_below_Def: "Def x \ Def y \ x = y" +by (simp add: below_lift_def Def_def Abs_lift_inverse lift_def) -lemma Def_less_is_eq [simp]: "Def x \ y \ Def x = y" -by (induct y, simp, simp add: Def_inject_less_eq) +lemma Def_below_iff [simp]: "Def x \ y \ Def x = y" +by (induct y, simp, simp add: Def_below_Def) subsection {* Lift is flat *} @@ -134,7 +134,7 @@ "(\x. f x \ g x) \ (FLIFT x. f x) \ (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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/LowerPD.thy --- 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: "\s \\ t; u \\ v\ \ PDPlus s u \\ PDPlus t v" unfolding lower_le_def Rep_PDPlus by fast -lemma PDPlus_lower_less: "t \\ PDPlus t u" +lemma PDPlus_lower_le: "t \\ 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 \ Rep_lower_pd (\i. Y i) = (\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 \ xs +\ ys" +lemma lower_plus_below1: "xs \ xs +\ 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 \ xs +\ ys" -by (subst lower_plus_commute, rule lower_plus_less1) +lemma lower_plus_below2: "ys \ xs +\ ys" +by (subst lower_plus_commute, rule lower_plus_below1) lemma lower_plus_least: "\xs \ zs; ys \ zs\ \ xs +\ ys \ 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 +\ ys \ zs \ xs \ zs \ ys \ 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}\ \ ys +\ zs \ {x}\ \ ys \ {x}\ \ 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}\ \ {y}\ \ x \ y" +lemma lower_unit_below_iff [simp]: "{x}\ \ {y}\ \ x \ 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\x" in compact_basis.compact_imp_principal, simp) apply (cut_tac x="approx i\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}\ = {y}\ \ x = y" by (simp add: po_eq_conv) @@ -330,18 +330,18 @@ lemma lower_plus_strict_iff [simp]: "xs +\ ys = \ \ xs = \ \ ys = \" 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]: "\ +\ 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 +\ \ = 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 \\ u \ lower_bind_basis t \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/One.thy --- 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: "\P \; P ONE\ \ P x" by (cases x rule: oneE) simp_all -lemma dist_less_one [simp]: "\ ONE \ \" +lemma dist_below_one [simp]: "\ ONE \ \" unfolding ONE_def by simp -lemma less_ONE [simp]: "x \ ONE" +lemma below_ONE [simp]: "x \ ONE" by (induct x rule: one_induct) simp_all -lemma ONE_less_iff [simp]: "ONE \ x \ x = ONE" +lemma ONE_below_iff [simp]: "ONE \ x \ x = ONE" by (induct x rule: one_induct) simp_all -lemma dist_eq_one [simp]: "ONE \ \" "\ \ ONE" -unfolding ONE_def by simp_all +lemma ONE_defined [simp]: "ONE \ \" +unfolding ONE_def by simp lemma one_neq_iffs [simp]: "x \ ONE \ x = \" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Pcpo.thy --- 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 \ \x :: 'a::po. range S <<| x" + assumes cpo: "chain S \ \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 \ 'a::cpo) \ range S <<| (\i. S i)" -by (fast dest: cpo elim: lubI) +lemma cpo_lubI: "chain S \ range S <<| (\i. S i)" + by (fast dest: cpo elim: lubI) -lemma thelubE: "\chain S; (\i. S i) = (l::'a::cpo)\ \ range S <<| l" -by (blast dest: cpo intro: lubI) +lemma thelubE: "\chain S; (\i. S i) = l\ \ range S <<| l" + by (blast dest: cpo intro: lubI) text {* Properties of the lub *} -lemma is_ub_thelub: "chain (S::nat \ 'a::cpo) \ S x \ (\i. S i)" -by (blast dest: cpo intro: lubI [THEN is_ub_lub]) +lemma is_ub_thelub: "chain S \ S x \ (\i. S i)" + by (blast dest: cpo intro: lubI [THEN is_ub_lub]) lemma is_lub_thelub: - "\chain (S::nat \ 'a::cpo); range S <| x\ \ (\i. S i) \ x" -by (blast dest: cpo intro: lubI [THEN is_lub_lub]) + "\chain S; range S <| x\ \ (\i. S i) \ x" + by (blast dest: cpo intro: lubI [THEN is_lub_lub]) lemma lub_range_mono: - "\range X \ range Y; chain Y; chain (X::nat \ 'a::cpo)\ + "\range X \ range Y; chain Y; chain X\ \ (\i. X i) \ (\i. Y i)" apply (erule is_lub_thelub) apply (rule ub_rangeI) @@ -45,8 +45,8 @@ done lemma lub_range_shift: - "chain (Y::nat \ 'a::cpo) \ (\i. Y (i + j)) = (\i. Y i)" -apply (rule antisym_less) + "chain Y \ (\i. Y (i + j)) = (\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 \ max_in_chain i Y = ((\i. Y i) = ((Y i)::'a::cpo))" + "chain Y \ max_in_chain i Y = ((\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 "\"} relation between two chains is preserved by their lubs *} lemma lub_mono: - "\chain (X::nat \ 'a::cpo); chain Y; \i. X i \ Y i\ + "\chain X; chain Y; \i. X i \ Y i\ \ (\i. X i) \ (\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: - "\chain (X::nat \ 'a::cpo); chain Y; \k. X k = Y k\ + "\chain X; chain Y; \k. X k = Y k\ \ (\i. X i) = (\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: - "\\j. \i>j. X i = Y i; chain (X::nat \ 'a::cpo); chain Y\ + "\\j. \i>j. X i = Y i; chain X; chain Y\ \ (\i. X i) \ (\i. Y i)" apply (erule exE) apply (subgoal_tac "(\i. X (i + Suc j)) \ (\i. Y (i + Suc j))") @@ -104,23 +104,22 @@ done lemma lub_equal2: - "\\j. \i>j. X i = Y i; chain (X::nat \ 'a::cpo); chain Y\ + "\\j. \i>j. X i = Y i; chain X; chain Y\ \ (\i. X i) = (\i. Y i)" -by (blast intro: antisym_less lub_mono2 sym) + by (blast intro: below_antisym lub_mono2 sym) lemma lub_mono3: - "\chain (Y::nat \ 'a::cpo); chain X; \i. \j. Y i \ X j\ + "\chain Y; chain X; \i. \j. Y i \ X j\ \ (\i. Y i) \ (\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 \ nat \ 'a::cpo" assumes 1: "\j. chain (\i. Y i j)" assumes 2: "\i. chain (\j. Y i j)" shows "chain (\i. \j. Y i j)" @@ -130,14 +129,13 @@ done lemma diag_lub: - fixes Y :: "nat \ nat \ 'a::cpo" assumes 1: "\j. chain (\i. Y i j)" assumes 2: "\i. chain (\j. Y i j)" shows "(\i. \j. Y i j) = (\i. Y i i)" -proof (rule antisym_less) +proof (rule below_antisym) have 3: "chain (\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 \ nat \ 'a::cpo" assumes 1: "\j. chain (\i. Y i j)" assumes 2: "\i. chain (\j. Y i j)" shows "(\i. \j. Y i j) = (\j. \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: "\x. \y. x \ y" +begin -definition - UU :: "'a::pcpo" where +definition UU :: 'a where "UU = (THE x. \y. x \ 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]: "\ \ x" by (rule UU_least [THEN spec]) -lemma UU_reorient: "(\ = x) = (x = \)" -by auto +end + +text {* Simproc to rewrite @{term "\ = x"} to @{term "x = \"}. *} -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 ("\ = x") = ReorientProc.proc + +context pcpo +begin text {* useful lemmas about @{term \} *} -lemma less_UU_iff [simp]: "(x \ \) = (x = \)" +lemma below_UU_iff [simp]: "(x \ \) = (x = \)" by (simp add: po_eq_conv) lemma eq_UU_iff: "(x = \) = (x \ \)" @@ -225,9 +216,6 @@ lemma UU_I: "x \ \ \ x = \" by (subst eq_UU_iff) -lemma not_less2not_eq: "\ (x::'a::po) \ y \ x \ y" -by auto - lemma chain_UU_I: "\chain Y; (\i. Y i) = \\ \ \i. Y i = \" apply (rule allI) apply (rule UU_I) @@ -242,49 +230,53 @@ done lemma chain_UU_I_inverse2: "(\i. Y i) \ \ \ \i::nat. Y i \ \" -by (blast intro: chain_UU_I_inverse) + by (blast intro: chain_UU_I_inverse) lemma notUU_I: "\x \ y; x \ \\ \ y \ \" -by (blast intro: UU_I) + by (blast intro: UU_I) lemma chain_mono2: "\\j. Y j \ \; chain Y\ \ \j. \i>j. Y i \ \" -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 \ \n. max_in_chain n Y" +begin -class chfin = po + - assumes chfin: "chain Y \ \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) \ y \ x = \ \ x = y" +lemma chfin2finch: "chain Y \ 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 \ y \ x = \ \ 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 "\i. Y i = \") 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 \ y) = (x = \ \ x = y)" -by (safe dest!: ax_flat) + by (safe dest!: ax_flat) -lemma flat_eq: "(a::'a::flat) \ \ \ a \ b = (a = b)" -by (safe dest!: ax_flat) +lemma flat_eq: "a \ \ \ a \ b = (a = b)" + by (safe dest!: ax_flat) -lemma chfin2finch: "chain (Y::nat \ 'a::chfin) \ 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 \ y \ 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 \ 'a::discrete_cpo)" + assumes S: "chain S" shows "\x. S = (\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 \ '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: - "\chain Y; \i. P (Y i); - \Y. \chain Y; \i. P (Y i); \ finite_chain Y\ \ P (\i. Y i)\ - \ P (\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: - "\chain Y; \i. P (Y i); \Y. \chain Y; \i. P (Y i); - \i. \j>i. Y i \ Y j \ Y i \ Y j\ \ P (\i. Y i)\ - \ P (\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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Pcpodef.thy --- 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 \ 'b::type" assumes type: "type_definition Rep Abs A" - and less: "op \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ 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 \ 'a::sq_ord \ bool"}) *} +setup {* Sign.add_const_constraint (@{const_name Porder.below}, + SOME @{typ "'a::below \ 'a::below \ bool"}) *} subsection {* Proving a subtype is finite *} @@ -58,9 +58,9 @@ subsection {* Proving a subtype is chain-finite *} lemma monofun_Rep: - assumes less: "op \ \ \x y. Rep x \ Rep y" + assumes below: "op \ \ \x y. Rep x \ 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 \ 'b::po" assumes type: "type_definition Rep Abs A" - and less: "op \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ 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 \ 'b::po" assumes type: "type_definition Rep Abs A" - and less: "op \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and adm: "adm (\x. x \ A)" shows "chain S \ Rep (Abs (\i. Rep (S i))) = (\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 \ 'b::po" assumes type: "type_definition Rep Abs A" - and less: "op \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and adm: "adm (\x. x \ A)" shows "chain S \ range S <<| Abs (\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 \ 'b::po" assumes type: "type_definition Rep Abs A" - and less: "op \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and adm: "adm (\x. x \ A)" shows "OFCLASS('b, cpo_class)" proof fix S::"nat \ 'b" assume "chain S" hence "range S <<| Abs (\i. Rep (S i))" - by (rule typedef_lub [OF type less adm]) + by (rule typedef_lub [OF type below adm]) thus "\x. range S <<| x" .. qed @@ -136,14 +136,14 @@ theorem typedef_cont_Rep: fixes Abs :: "'a::cpo \ 'b::cpo" assumes type: "type_definition Rep Abs A" - and less: "op \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and adm: "adm (\x. x \ 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 \ \ \x y. Rep x \ Rep y" + assumes below: "op \ \ \x y. Rep x \ Rep y" shows "range (\i. Rep (S i)) <<| Rep x \ 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 \ 'b::cpo" fixes f :: "'c::cpo \ 'a::cpo" assumes type: "type_definition Rep Abs A" - and less: "op \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and adm: "adm (\x. x \ A)" (* not used *) and f_in_A: "\x. f x \ A" and cont_f: "cont f" shows "cont (\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 \ 'b::cpo" assumes type: "type_definition Rep Abs A" - and less: "op \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and adm: "adm (\x. x \ A)" shows "compact (Rep k) \ 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 (\x. \ Rep k \ x)" with cont_Rep have "adm (\x. \ Rep k \ Rep x)" by (rule adm_subst) - thus "adm (\x. \ k \ x)" by (unfold less) + thus "adm (\x. \ k \ x)" by (unfold below) qed subsection {* Proving a subtype is pointed *} @@ -205,13 +205,13 @@ theorem typedef_pcpo_generic: fixes Abs :: "'a::cpo \ 'b::cpo" assumes type: "type_definition Rep Abs A" - and less: "op \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and z_in_A: "z \ A" and z_least: "\x. x \ A \ z \ 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 \ 'b::cpo" assumes type: "type_definition Rep Abs A" - and less: "op \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and UU_in_A: "\ \ 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 \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and UU_in_A: "\ \ A" shows "Abs \ = \" - 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 \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and UU_in_A: "\ \ A" shows "Rep \ = \" - 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 \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and UU_in_A: "\ \ A" shows "x \ A \ (Abs x = \) = (x = \)" - 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 \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and UU_in_A: "\ \ A" shows "(Rep x = \) = (x = \)" - 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 \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and UU_in_A: "\ \ A" shows "\x \ \; x \ A\ \ Abs x \ \" -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 \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and UU_in_A: "\ \ A" shows "x \ \ \ Rep x \ \" -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 \ 'b::pcpo" assumes type: "type_definition Rep Abs A" - and less: "op \ \ \x y. Rep x \ Rep y" + and below: "op \ \ \x y. Rep x \ Rep y" and UU_in_A: "\ \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Porder.thy --- 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 \ 'a \ bool" +class below = + fixes below :: "'a \ 'a \ bool" +begin notation - sq_le (infixl "<<" 55) + below (infixl "<<" 55) notation (xsymbols) - sq_le (infixl "\" 55) + below (infixl "\" 55) + +lemma below_eq_trans: "\a \ b; b = c\ \ a \ c" + by (rule subst) + +lemma eq_below_trans: "\a = b; b \ c\ \ a \ c" + by (rule ssubst) -class po = sq_ord + - assumes refl_less [iff]: "x \ x" - assumes trans_less: "\x \ y; y \ z\ \ x \ z" - assumes antisym_less: "\x \ y; y \ x\ \ x = y" +end + +class po = below + + assumes below_refl [iff]: "x \ x" + assumes below_trans: "x \ y \ y \ z \ x \ z" + assumes below_antisym: "x \ y \ y \ x \ x = y" +begin text {* minimal fixes least element *} -lemma minimal2UU[OF allI] : "\x::'a::po. uu \ x \ uu = (THE u. \y. u \ y)" -by (blast intro: theI2 antisym_less) +lemma minimal2UU[OF allI] : "\x. uu \ x \ uu = (THE u. \y. u \ 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 \ x \ y \ y \ x" + by simp -lemma antisym_less_inverse: "(x::'a::po) = y \ x \ y \ y \ x" -by simp - -lemma box_less: "\(a::'a::po) \ b; c \ a; b \ d\ \ c \ d" -by (rule trans_less [OF trans_less]) +lemma box_below: "a \ b \ c \ a \ b \ d \ c \ d" + by (rule below_trans [OF below_trans]) -lemma po_eq_conv: "((x::'a::po) = y) = (x \ y \ y \ x)" -by (fast elim!: antisym_less_inverse intro!: antisym_less) - -lemma rev_trans_less: "\(y::'a::po) \ z; x \ y\ \ x \ z" -by (rule trans_less) +lemma po_eq_conv: "x = y \ x \ y \ y \ x" + by (fast intro!: below_antisym) -lemma sq_ord_less_eq_trans: "\a \ b; b = c\ \ a \ c" -by (rule subst) +lemma rev_below_trans: "y \ z \ x \ y \ x \ z" + by (rule below_trans) -lemma sq_ord_eq_less_trans: "\a = b; b \ c\ \ a \ c" -by (rule ssubst) +lemma not_below2not_eq: "\ x \ y \ x \ 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] \ bool" (infixl "<|" 55) where - "(S <| x) = (\y. y \ S \ y \ x)" +definition is_ub :: "'a set \ 'a \ bool" (infixl "<|" 55) where + "S <| x \ (\y. y \ S \ y \ x)" lemma is_ubI: "(\x. x \ S \ x \ u) \ S <| u" -by (simp add: is_ub_def) + by (simp add: is_ub_def) lemma is_ubD: "\S <| u; x \ S\ \ x \ u" -by (simp add: is_ub_def) + by (simp add: is_ub_def) lemma ub_imageI: "(\x. x \ S \ f x \ u) \ (\x. f x) ` S <| u" -unfolding is_ub_def by fast + unfolding is_ub_def by fast lemma ub_imageD: "\f ` S <| u; x \ S\ \ f x \ u" -unfolding is_ub_def by fast + unfolding is_ub_def by fast lemma ub_rangeI: "(\i. S i \ x) \ range S <| x" -unfolding is_ub_def by fast + unfolding is_ub_def by fast lemma ub_rangeD: "range S <| x \ S i \ 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 \ y \ A <| y)" -unfolding is_ub_def by fast + unfolding is_ub_def by fast lemma is_ub_upward: "\S <| x; x \ y\ \ 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] \ bool" (infixl "<<|" 55) where - "(S <<| x) = (S <| x \ (\u. S <| u \ x \ u))" +definition is_lub :: "'a set \ 'a \ bool" (infixl "<<|" 55) where + "S <<| x \ S <| x \ (\u. S <| u \ x \ u)" -definition - lub :: "'a set \ 'a::po" where +definition lub :: "'a set \ 'a" where "lub S = (THE x. S <<| x)" +end + syntax "_BLub" :: "[pttrn, 'a set, 'b] \ '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 \ S <| x" -unfolding is_lub_def by fast + unfolding is_lub_def by fast lemma is_lub_lub: "\S <<| x; S <| u\ \ x \ u" -unfolding is_lub_def by fast + unfolding is_lub_def by fast lemma is_lubI: "\S <| x; \u. S <| u \ x \ u\ \ S <<| x" -unfolding is_lub_def by fast + unfolding is_lub_def by fast text {* lubs are unique *} lemma unique_lub: "\S <<| x; S <<| y\ \ 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 \ 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 \ y \ {x, y} <<| y" -by (simp add: is_lub_def) + by (simp add: is_lub_def) lemma lub_bin: "x \ y \ lub {x, y} = y" -by (rule is_lub_bin [THEN thelubI]) + by (rule is_lub_bin [THEN thelubI]) lemma is_lub_maximal: "\S <| x; x \ S\ \ S <<| x" -by (erule is_lubI, erule (1) is_ubD) + by (erule is_lubI, erule (1) is_ubD) lemma lub_maximal: "\S <| x; x \ S\ \ lub S = x" -by (rule is_lub_maximal [THEN thelubI]) + by (rule is_lub_maximal [THEN thelubI]) subsection {* Countable chains *} -definition +definition chain :: "(nat \ 'a) \ bool" where -- {* Here we use countable chains and I prefer to code them as functions! *} - chain :: "(nat \ 'a::po) \ bool" where "chain Y = (\i. Y i \ Y (Suc i))" lemma chainI: "(\i. Y i \ Y (Suc i)) \ chain Y" -unfolding chain_def by fast + unfolding chain_def by fast lemma chainE: "chain Y \ Y i \ Y (Suc i)" -unfolding chain_def by fast + unfolding chain_def by fast text {* chains are monotone functions *} lemma chain_mono_less: "\chain Y; i < j\ \ Y i \ 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: "\chain Y; i \ j\ \ Y i \ 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 \ chain (\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 \ S i \ x" -by (rule is_lubD1 [THEN ub_rangeD]) + by (rule is_lubD1 [THEN ub_rangeD]) lemma is_ub_range_shift: "chain S \ range (\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 \ range (\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 (\i. c)" -by (simp add: chainI) + by (simp add: chainI) lemma lub_const: "range (\x. c) <<| c" by (blast dest: ub_rangeD intro: is_lubI ub_rangeI) lemma thelub_const [simp]: "(\i. c) = c" -by (rule lub_const [THEN thelubI]) + by (rule lub_const [THEN thelubI]) subsection {* Finite chains *} -definition +definition max_in_chain :: "nat \ (nat \ 'a) \ bool" where -- {* finite chains, needed for monotony of continuous functions *} - max_in_chain :: "[nat, nat \ 'a::po] \ bool" where - "max_in_chain i C = (\j. i \ j \ C i = C j)" + "max_in_chain i C \ (\j. i \ j \ C i = C j)" -definition - finite_chain :: "(nat \ 'a::po) \ bool" where +definition finite_chain :: "(nat \ 'a) \ bool" where "finite_chain C = (chain C \ (\i. max_in_chain i C))" text {* results about finite chains *} lemma max_in_chainI: "(\j. i \ j \ Y i = Y j) \ max_in_chain i Y" -unfolding max_in_chain_def by fast + unfolding max_in_chain_def by fast lemma max_in_chainD: "\max_in_chain i Y; i \ j\ \ Y i = Y j" -unfolding max_in_chain_def by fast + unfolding max_in_chain_def by fast lemma finite_chainI: "\chain C; max_in_chain i C\ \ finite_chain C" -unfolding finite_chain_def by fast + unfolding finite_chain_def by fast lemma finite_chainE: "\finite_chain C; \i. \chain C; max_in_chain i C\ \ R\ \ R" -unfolding finite_chain_def by fast + unfolding finite_chain_def by fast lemma lub_finch1: "\chain C; max_in_chain i C\ \ 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 \ y \ chain (\i. if i=0 then x else y)" -by (rule chainI, simp) + by (rule chainI, simp) lemma bin_chainmax: "x \ y \ max_in_chain (Suc 0) (\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 \ y \ range (\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: "\Y i = c; \i. Y i \ c\ \ 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 \ bool" where - "directed S = ((\x. x \ S) \ (\x\S. \y\S. \z\S. x \ z \ y \ z))" +definition directed :: "'a set \ bool" where + "directed S \ (\x. x \ S) \ (\x\S. \y\S. \z\S. x \ z \ y \ z)" lemma directedI: assumes 1: "\z. z \ S" assumes 2: "\x y. \x \ S; y \ S\ \ \z\S. x \ z \ y \ z" shows "directed S" -unfolding directed_def using prems by fast + unfolding directed_def using prems by fast lemma directedD1: "directed S \ \z. z \ S" -unfolding directed_def by fast + unfolding directed_def by fast lemma directedD2: "\directed S; x \ S; y \ S\ \ \z\S. x \ z \ y \ z" -unfolding directed_def by fast + unfolding directed_def by fast lemma directedE1: assumes S: "directed S" obtains z where "z \ S" -by (insert directedD1 [OF S], fast) + by (insert directedD1 [OF S], fast) lemma directedE2: assumes S: "directed S" assumes x: "x \ S" and y: "y \ S" obtains z where "z \ S" "x \ z" "y \ z" -by (insert directedD2 [OF S x y], fast) + by (insert directedD2 [OF S x y], fast) lemma directed_finiteI: assumes U: "\U. \finite U; U \ S\ \ \z\S. U <| z" @@ -395,13 +405,13 @@ qed lemma not_directed_empty [simp]: "\ 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 \ y \ directed {x, y}" -by (rule directedI, auto) + by (rule directedI, auto) lemma directed_chain: "chain S \ 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: + "\chain Y; \i. P (Y i); + \Y. \chain Y; \i. P (Y i); \ finite_chain Y\ \ P (\i. Y i)\ + \ P (\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: + "\chain Y; \i. P (Y i); \Y. \chain Y; \i. P (Y i); + \i. \j>i. Y i \ Y j \ Y i \ Y j\ \ P (\i. Y i)\ + \ P (\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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Product_Cpo.thy --- 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 \ (y::unit) \ True" + below_unit_def [simp]: "x \ (y::unit) \ 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 \) \ \p1 p2. (fst p1 \ fst p2 \ snd p1 \ snd p2)" + below_prod_def: "(op \) \ \p1 p2. (fst p1 \ fst p2 \ snd p1 \ snd p2)" instance .. end @@ -45,26 +45,26 @@ proof fix x :: "'a \ 'b" show "x \ x" - unfolding less_cprod_def by simp + unfolding below_prod_def by simp next fix x y :: "'a \ 'b" assume "x \ y" "y \ 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 \ 'b" assume "x \ y" "y \ z" thus "x \ 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: "\fst p \ fst q; snd p \ snd q\ \ p \ q" -unfolding less_cprod_def by simp +lemma prod_belowI: "\fst p \ fst q; snd p \ snd q\ \ p \ q" +unfolding below_prod_def by simp -lemma Pair_less_iff [simp]: "(a, b) \ (c, d) \ a \ c \ b \ d" -unfolding less_cprod_def by simp +lemma Pair_below_iff [simp]: "(a, b) \ (c, d) \ a \ c \ b \ 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: "\range X <<| x; range Y <<| y\ \ range (\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 \ 'b" show "x \ y \ 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: "(\, \) \ 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 (\x. f x)" assumes g: "cont (\x. g x)" shows "cont (\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: "\a b. cont (\x. f x a b)" + assumes f2: "\x b. cont (\a. f x a b)" + assumes f3: "\x a. cont (\b. f x a b)" + assumes g: "cont (\x. g x)" + shows "cont (\x. split (\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 (\p. f (fst p) (snd p)) \ cont (\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 (\p. f (fst p) (snd p)) \ cont (\y. f x y)" +by (drule cont_compose [OF _ cont_pair2], simp) + +lemma cont2cont_split' [cont2cont]: + assumes f: "cont (\p. f (fst p) (fst (snd p)) (snd (snd p)))" + assumes g: "cont (\x. g x)" + shows "cont (\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 \ 'b) \ y \ x \ (y, snd x)" -unfolding less_cprod_def by simp +lemma fst_below_iff: "fst (x::'a \ 'b) \ y \ x \ (y, snd x)" +unfolding below_prod_def by simp -lemma snd_less_iff: "snd (x::'a \ 'b) \ y = x \ (fst x, y)" -unfolding less_cprod_def by simp +lemma snd_below_iff: "snd (x::'a \ 'b) \ y \ x \ (fst x, y)" +unfolding below_prod_def by simp lemma compact_fst: "compact x \ compact (fst x)" -by (rule compactI, simp add: fst_less_iff) +by (rule compactI, simp add: fst_below_iff) lemma compact_snd: "compact x \ compact (snd x)" -by (rule compactI, simp add: snd_less_iff) +by (rule compactI, simp add: snd_below_iff) lemma compact_Pair: "\compact x; compact y\ \ 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) \ compact x \ compact y" apply (safe intro!: compact_Pair) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Sprod.thy --- 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" ("(_ \/ _)" [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:) = \) = (x = \ \ y = \)" by (simp add: Rep_Sprod_simps strictify_conv_if) -lemma spair_less_iff: +lemma spair_below_iff: "((:a, b:) \ (:c, d:)) = (a = \ \ b = \ \ (a \ c \ b \ d))" by (simp add: Rep_Sprod_simps strictify_conv_if) @@ -160,38 +160,38 @@ lemma surjective_pairing_Sprod2: "(:sfst\p, ssnd\p:) = p" by (cases p, simp_all) -lemma less_sprod: "x \ y = (sfst\x \ sfst\y \ ssnd\x \ ssnd\y)" -apply (simp add: less_Sprod_def sfst_def ssnd_def cont_Rep_Sprod) -apply (rule less_cprod) +lemma below_sprod: "x \ y = (sfst\x \ sfst\y \ ssnd\x \ ssnd\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\x = sfst\y \ ssnd\x = ssnd\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: "\x \ \; y \ \\ \ (:x, y:) \ (:a, b:) = (x \ a \ y \ b)" apply (cases "a = \", simp) apply (cases "b = \", simp) -apply (simp add: less_sprod) +apply (simp add: below_sprod) done -lemma sfst_less_iff: "sfst\x \ y = x \ (:y, ssnd\x:)" +lemma sfst_below_iff: "sfst\x \ y = x \ (:y, ssnd\x:)" apply (cases "x = \", simp, cases "y = \", simp) -apply (simp add: less_sprod) +apply (simp add: below_sprod) done -lemma ssnd_less_iff: "ssnd\x \ y = x \ (:sfst\x, y:)" +lemma ssnd_below_iff: "ssnd\x \ y = x \ (:sfst\x, y:)" apply (cases "x = \", simp, cases "y = \", simp) -apply (simp add: less_sprod) +apply (simp add: below_sprod) done subsection {* Compactness *} lemma compact_sfst: "compact x \ compact (sfst\x)" -by (rule compactI, simp add: sfst_less_iff) +by (rule compactI, simp add: sfst_below_iff) lemma compact_ssnd: "compact x \ compact (ssnd\x)" -by (rule compactI, simp add: ssnd_less_iff) +by (rule compactI, simp add: ssnd_below_iff) lemma compact_spair: "\compact x; compact y\ \ compact (:x, y:)" by (rule compact_Sprod, simp add: Rep_Sprod_spair strictify_conv_if) @@ -224,7 +224,7 @@ assume "x \ y" thus "x = \ \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Ssum.thy --- 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" ("(_ \/ _)" [21, 20] 20) @@ -61,17 +61,17 @@ text {* Ordering *} -lemma sinl_less [simp]: "(sinl\x \ sinl\y) = (x \ y)" -by (simp add: less_Ssum_def Rep_Ssum_sinl strictify_conv_if) +lemma sinl_below [simp]: "(sinl\x \ sinl\y) = (x \ y)" +by (simp add: below_Ssum_def Rep_Ssum_sinl strictify_conv_if) -lemma sinr_less [simp]: "(sinr\x \ sinr\y) = (x \ y)" -by (simp add: less_Ssum_def Rep_Ssum_sinr strictify_conv_if) +lemma sinr_below [simp]: "(sinr\x \ sinr\y) = (x \ y)" +by (simp add: below_Ssum_def Rep_Ssum_sinr strictify_conv_if) -lemma sinl_less_sinr [simp]: "(sinl\x \ sinr\y) = (x = \)" -by (simp add: less_Ssum_def Rep_Ssum_sinl Rep_Ssum_sinr strictify_conv_if) +lemma sinl_below_sinr [simp]: "(sinl\x \ sinr\y) = (x = \)" +by (simp add: below_Ssum_def Rep_Ssum_sinl Rep_Ssum_sinr strictify_conv_if) -lemma sinr_less_sinl [simp]: "(sinr\x \ sinl\y) = (x = \)" -by (simp add: less_Ssum_def Rep_Ssum_sinl Rep_Ssum_sinr strictify_conv_if) +lemma sinr_below_sinl [simp]: "(sinr\x \ sinl\y) = (x = \)" +by (simp add: below_Ssum_def Rep_Ssum_sinl Rep_Ssum_sinr strictify_conv_if) text {* Equality *} @@ -167,10 +167,10 @@ "\\x. p = sinl\x \ Q; \y. p = sinr\y \ Q\ \ Q" by (cases p, simp only: sinl_strict [symmetric], simp, simp) -lemma less_sinlD: "p \ sinl\x \ \y. p = sinl\y \ y \ x" +lemma below_sinlD: "p \ sinl\x \ \y. p = sinl\y \ y \ x" by (cases p, rule_tac x="\" in exI, simp_all) -lemma less_sinrD: "p \ sinr\x \ \y. p = sinr\y \ y \ x" +lemma below_sinrD: "p \ sinr\x \ \y. p = sinr\y \ y \ x" by (cases p, rule_tac x="\" 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Sum_Cpo.thy --- 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 \ y \ case x of +definition below_sum_def: + "x \ y \ case x of Inl a \ (case y of Inl b \ a \ b | Inr b \ False) | Inr a \ (case y of Inl b \ False | Inr b \ a \ b)" instance .. end -lemma Inl_less_iff [simp]: "Inl x \ Inl y = x \ y" -unfolding less_sum_def by simp +lemma Inl_below_Inl [simp]: "Inl x \ Inl y = x \ y" +unfolding below_sum_def by simp -lemma Inr_less_iff [simp]: "Inr x \ Inr y = x \ y" -unfolding less_sum_def by simp +lemma Inr_below_Inr [simp]: "Inr x \ Inr y = x \ y" +unfolding below_sum_def by simp -lemma Inl_less_Inr [simp]: "\ Inl x \ Inr y" -unfolding less_sum_def by simp +lemma Inl_below_Inr [simp]: "\ Inl x \ Inr y" +unfolding below_sum_def by simp -lemma Inr_less_Inl [simp]: "\ Inr x \ Inl y" -unfolding less_sum_def by simp +lemma Inr_below_Inl [simp]: "\ Inr x \ Inl y" +unfolding below_sum_def by simp lemma Inl_mono: "x \ y \ Inl x \ Inl y" by simp @@ -39,20 +39,20 @@ lemma Inr_mono: "x \ y \ Inr x \ Inr y" by simp -lemma Inl_lessE: "\Inl a \ x; \b. \x = Inl b; a \ b\ \ R\ \ R" +lemma Inl_belowE: "\Inl a \ x; \b. \x = Inl b; a \ b\ \ R\ \ R" by (cases x, simp_all) -lemma Inr_lessE: "\Inr a \ x; \b. \x = Inr b; a \ b\ \ R\ \ R" +lemma Inr_belowE: "\Inr a \ x; \b. \x = Inr b; a \ b\ \ R\ \ 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: "\x \ y; \a b. \x = Inl a; y = Inl b; a \ b\ \ R; \a b. \x = Inr a; y = Inr b; a \ b\ \ R\ \ 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 \ y" and "y \ 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 \ y" and "y \ z" thus "x \ 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 (\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 (\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 \ range (\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 \ cont (\x. Inl (f x))" -by (fast intro: contI is_lub_Inl elim: contE) - -lemma cont2cont_Inr [simp]: "cont f \ cont (\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: "\a. cont (\x. f x a)" and f2: "\x. cont (\a. f x a)" assumes g1: "\b. cont (\x. g x b)" and g2: "\x. cont (\b. g x b)" assumes h: "cont (\x. h x)" shows "cont (\x. case h x of Inl a \ f x a | Inr b \ 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 (\p. f (fst p) (snd p))" + assumes g: "cont (\p. g (fst p) (snd p))" + assumes h: "cont (\x. h x)" + shows "cont (\x. case h x of Inl a \ f x a | Inr b \ 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 \ 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 *} diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Tools/adm_tac.ML --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Tools/cont_consts.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Tools/cont_proc.ML --- 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 **) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Tools/domain/domain_axioms.ML --- 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"; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Tools/domain/domain_extender.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Tools/domain/domain_library.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Tools/domain/domain_syntax.ML --- 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]) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Tools/domain/domain_theorems.ML --- 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 *) diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Tools/fixrec_package.ML --- 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"; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Tools/pcpodef_package.ML --- 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); diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Tr.thy --- 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]: "\ TT \ \" "\ FF \ \" "\ TT \ FF" "\ FF \ TT" unfolding TT_def FF_def by simp_all @@ -45,16 +45,16 @@ "TT \ \" "FF \ \" "TT \ FF" "\ \ TT" "\ \ FF" "FF \ TT" unfolding TT_def FF_def by simp_all -lemma TT_less_iff [simp]: "TT \ x \ x = TT" +lemma TT_below_iff [simp]: "TT \ x \ x = TT" by (induct x rule: tr_induct) simp_all -lemma FF_less_iff [simp]: "FF \ x \ x = FF" +lemma FF_below_iff [simp]: "FF \ x \ x = FF" by (induct x rule: tr_induct) simp_all -lemma not_less_TT_iff [simp]: "\ (x \ TT) \ x = FF" +lemma not_below_TT_iff [simp]: "\ (x \ TT) \ x = FF" by (induct x rule: tr_induct) simp_all -lemma not_less_FF_iff [simp]: "\ (x \ FF) \ x = TT" +lemma not_below_FF_iff [simp]: "\ (x \ FF) \ x = TT" by (induct x rule: tr_induct) simp_all diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Universal.thy --- 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 \ Rep_udom (\i. Y i) = (\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 \ insert a A" and "(if x \ a then a else x) \ y" thus "(if x \ 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 \ n \ 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 \ basis_prj a \ 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 \ range (basis_emb :: 'a compact_basis \ nat)") diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/Up.thy --- 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 \) \ (\x y. case x of Ibottom \ True | Iup a \ (case y of Ibottom \ False | Iup b \ a \ b))" @@ -38,13 +38,13 @@ end lemma minimal_up [iff]: "Ibottom \ z" -by (simp add: less_up_def) +by (simp add: below_up_def) -lemma not_Iup_less [iff]: "\ Iup x \ Ibottom" -by (simp add: less_up_def) +lemma not_Iup_below [iff]: "\ Iup x \ Ibottom" +by (simp add: below_up_def) -lemma Iup_less [iff]: "(Iup x \ Iup y) = (x \ y)" -by (simp add: less_up_def) +lemma Iup_below [iff]: "(Iup x \ Iup y) = (x \ 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 \ 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 \ y" "y \ 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 \ y" "y \ z" thus "x \ 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 \ range (\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: "\chain Y; Y j \ Ibottom\ \ chain (\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: "\ up\x \ \" -by simp +by simp (* FIXME: remove? *) -lemma up_less [simp]: "(up\x \ up\y) = (x \ y)" +lemma up_below [simp]: "up\x \ up\y \ x \ y" by (simp add: up_def cont_Iup) lemma upE [cases type: u]: "\p = \ \ Q; \x. p = up\x \ Q\ \ Q" diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/UpperPD.thy --- 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: "\s \\ t; u \\ v\ \ PDPlus s u \\ PDPlus t v" unfolding upper_le_def Rep_PDPlus by fast -lemma PDPlus_upper_less: "PDPlus t u \\ t" +lemma PDPlus_upper_le: "PDPlus t u \\ 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 \ Rep_upper_pd (\i. Y i) = (\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 +\ ys \ xs" +lemma upper_plus_below1: "xs +\ ys \ 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 +\ ys \ ys" -by (subst upper_plus_commute, rule upper_plus_less1) +lemma upper_plus_below2: "xs +\ ys \ ys" +by (subst upper_plus_commute, rule upper_plus_below1) lemma upper_plus_greatest: "\xs \ ys; xs \ zs\ \ xs \ ys +\ 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 \ ys +\ zs \ xs \ ys \ xs \ 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 +\ ys \ {z}\ \ xs \ {z}\ \ ys \ {z}\" 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}\ \ {y}\ \ x \ y" +lemma upper_unit_below_iff [simp]: "{x}\ \ {y}\ \ x \ 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\x" in compact_basis.compact_imp_principal, simp) apply (cut_tac x="approx i\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}\ = {y}\ \ 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]: "\ +\ ys = \" -by (rule UU_I, rule upper_plus_less1) +by (rule UU_I, rule upper_plus_below1) lemma upper_plus_strict2 [simp]: "xs +\ \ = \" -by (rule UU_I, rule upper_plus_less2) +by (rule UU_I, rule upper_plus_below2) lemma upper_unit_strict_iff [simp]: "{x}\ = \ \ x = \" unfolding upper_unit_strict [symmetric] by (rule upper_unit_eq_iff) @@ -407,11 +407,11 @@ lemma upper_bind_basis_mono: "t \\ u \ upper_bind_basis t \ 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/ex/Domain_ex.thy --- /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\\\y = \" by simp + +text {* Constructors can be made lazy using the @{text "lazy"} keyword. *} + +domain d2 = d2a | d2b (lazy "d2") + +lemma "d2b\x \ \" by simp + +text {* Strict and lazy arguments may be mixed arbitrarily. *} + +domain d3 = d3a | d3b (lazy "d2") "d2" + +lemma "P (d3b\x\y = \) \ P (y = \)" 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 \ \ \ d4b_left\(d4b\x\y) = x" by simp + +text {* Mixfix declarations can be given for data constructors. *} + +domain d5 = d5a | d5b (lazy "d5") "d5" (infixl ":#:" 70) + +lemma "d5a \ 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 "\p::('a :*: 'b). p \ lfst\p :*: lsnd\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 \ 'b u" (lazy "('a :*: 'b) \ ('b \ '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 \ int lift" | d7b "'a \ 'a d7" | d7c "'a d7 \ '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 "\P \; P Tip; \x y. \x \ \; y \ \; P x; P y\ \ P (Branch\x\y)\ \ 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) = \" 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/ex/Fixrec_ex.thy --- 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 \ 'a" where "down\(up\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 \ 'b \ 'a" where "x \ \ \ from_sinl\(sinl\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 \ 'b \ 'a" where "from_sinl_up\(sinl\(up\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 \ 'b llist \ ('a \ 'b) llist" @@ -48,24 +48,59 @@ "lzip\(lCons\x\xs)\(lCons\y\ys) = lCons\\(lzip\xs\ys)" | "lzip\lNil\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\\\ys" "lzip\lNil\\" "lzip\(lCons\x\xs)\\" -text {* fixpat can also produce rules for missing cases *} +text {* @{text fixpat} can also produce rules for missing cases. *} fixpat lzip_undefs [simp]: "lzip\lNil\(lCons\y\ys)" "lzip\(lCons\x\xs)\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 \ 'b\<^sub>\ \ 'b" +where + "from_sinr_up\\ = \" +| "from_sinr_up\(sinr\(up\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 \ 'b \ 'b" +where + "seq\\\y = \" +| "x \ \ \ seq\x\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\(lCons\x\xs)\(lCons\y\ys)" @@ -97,16 +132,17 @@ "lzip2\\\ys" "lzip2\(lCons\x\xs)\\" -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 diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/ex/ROOT.ML --- 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"]; diff -r 657386d94f14 -r 0ce5f53fc65d src/HOLCF/ex/Stream.thy --- 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 = \ | #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 (* ----------------------------------------------------------------------- *) diff -r 657386d94f14 -r 0ce5f53fc65d src/Provers/Arith/cancel_div_mod.ML --- 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 ([],[]) diff -r 657386d94f14 -r 0ce5f53fc65d src/Pure/General/symbol.ML --- 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 *) diff -r 657386d94f14 -r 0ce5f53fc65d src/Pure/IsaMakefile --- 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 \ diff -r 657386d94f14 -r 0ce5f53fc65d src/Pure/Isar/class_target.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 diff -r 657386d94f14 -r 0ce5f53fc65d src/Pure/Isar/code.ML --- 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*) diff -r 657386d94f14 -r 0ce5f53fc65d src/Pure/Isar/code_unit.ML --- 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 *) diff -r 657386d94f14 -r 0ce5f53fc65d src/Pure/ProofGeneral/ROOT.ML --- 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"; diff -r 657386d94f14 -r 0ce5f53fc65d src/Pure/ProofGeneral/preferences.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; diff -r 657386d94f14 -r 0ce5f53fc65d src/Pure/Tools/ROOT.ML --- 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"; diff -r 657386d94f14 -r 0ce5f53fc65d src/Pure/Tools/find_theorems.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 || diff -r 657386d94f14 -r 0ce5f53fc65d src/Pure/axclass.ML --- 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 **) diff -r 657386d94f14 -r 0ce5f53fc65d src/Pure/name.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/Code_Generator.thy --- /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 diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/auto_solve.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/code/code_funcgr.ML --- 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*) diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/code/code_haskell.ML --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/code/code_ml.ML --- 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, diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/code/code_name.ML --- 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; diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/code/code_printer.ML --- 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 = diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/code/code_target.ML --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/code/code_thingol.ML --- 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*) diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/code/code_wellsorted.ML --- 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*) diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/nbe.ML --- 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 diff -r 657386d94f14 -r 0ce5f53fc65d src/Tools/quickcheck.ML --- 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