doc-src/IsarImplementation/Thy/ML.thy
author Walther Neuper <neuper@ist.tugraz.at>
Thu, 12 Aug 2010 15:03:34 +0200
branchisac-from-Isabelle2009-2
changeset 37913 20e3616b2d9c
parent 36164 532f4d1cb0fc
child 40261 0de42180febe
permissions -rw-r--r--
prepare reactivation of isac-update-Isa09-2
     1 theory "ML"
     2 imports Base
     3 begin
     4 
     5 chapter {* Advanced ML programming *}
     6 
     7 section {* Style *}
     8 
     9 text {*
    10   Like any style guide, also this one should not be interpreted dogmatically, but
    11   with care and discernment.  It consists of a collection of
    12   recommendations which have been turned out useful over long years of
    13   Isabelle system development and are supposed to support writing of readable
    14   and managable code.  Special cases encourage derivations,
    15   as far as you know what you are doing.
    16   \footnote{This style guide is loosely based on
    17   \url{http://caml.inria.fr/resources/doc/guides/guidelines.en.html}}
    18 
    19   \begin{description}
    20 
    21     \item[fundamental law of programming]
    22       Whenever writing code, keep in mind: A program is
    23       written once, modified ten times, and read
    24       hundred times.  So simplify its writing,
    25       always keep future modifications in mind,
    26       and never jeopardize readability.  Every second you hesitate
    27       to spend on making your code more clear you will
    28       have to spend ten times understanding what you have
    29       written later on.
    30 
    31     \item[white space matters]
    32       Treat white space in your code as if it determines
    33       the meaning of code.
    34 
    35       \begin{itemize}
    36 
    37         \item The space bar is the easiest key to find on the keyboard,
    38           press it as often as necessary. @{verbatim "2 + 2"} is better
    39           than @{verbatim "2+2"}, likewise @{verbatim "f (x, y)"} is
    40           better than @{verbatim "f(x,y)"}.
    41 
    42         \item Restrict your lines to 80 characters.  This will allow
    43           you to keep the beginning of a line in view while watching
    44           its end.\footnote{To acknowledge the lax practice of
    45           text editing these days, we tolerate as much as 100
    46           characters per line, but anything beyond 120 is not
    47           considered proper source text.}
    48 
    49         \item Ban tabulators; they are a context-sensitive formatting
    50           feature and likely to confuse anyone not using your favorite
    51           editor.\footnote{Some modern programming language even
    52           forbid tabulators altogether according to the formal syntax
    53           definition.}
    54 
    55         \item Get rid of trailing whitespace.  Instead, do not
    56           suppress a trailing newline at the end of your files.
    57 
    58         \item Choose a generally accepted style of indentation,
    59           then use it systematically throughout the whole
    60           application.  An indentation of two spaces is appropriate.
    61           Avoid dangling indentation.
    62 
    63       \end{itemize}
    64 
    65     \item[cut-and-paste succeeds over copy-and-paste]
    66        \emph{Never} copy-and-paste code when programming.  If you
    67         need the same piece of code twice, introduce a
    68         reasonable auxiliary function (if there is no
    69         such function, very likely you got something wrong).
    70         Any copy-and-paste will turn out to be painful 
    71         when something has to be changed later on.
    72 
    73     \item[comments]
    74       are a device which requires careful thinking before using
    75       it.  The best comment for your code should be the code itself.
    76       Prefer efforts to write clear, understandable code
    77       over efforts to explain nasty code.
    78 
    79     \item[functional programming is based on functions]
    80       Model things as abstract as appropriate.  Avoid unnecessarrily
    81       concrete datatype  representations.  For example, consider a function
    82       taking some table data structure as argument and performing
    83       lookups on it.  Instead of taking a table, it could likewise
    84       take just a lookup function.  Accustom
    85       your way of coding to the level of expressiveness a functional
    86       programming language is giving onto you.
    87 
    88     \item[tuples]
    89       are often in the way.  When there is no striking argument
    90       to tuple function arguments, just write your function curried.
    91 
    92     \item[telling names]
    93       Any name should tell its purpose as exactly as possible, while
    94       keeping its length to the absolutely necessary minimum.  Always
    95       give the same name to function arguments which have the same
    96       meaning. Separate words by underscores (@{verbatim
    97       int_of_string}, not @{verbatim intOfString}).\footnote{Some
    98       recent tools for Emacs include special precautions to cope with
    99       bumpy names in @{text "camelCase"}, e.g.\ for improved on-screen
   100       readability.  It is easier to abstain from using such names in the
   101       first place.}
   102 
   103   \end{description}
   104 *}
   105 
   106 
   107 section {* Thread-safe programming *}
   108 
   109 text {*
   110   Recent versions of Poly/ML (5.2.1 or later) support robust
   111   multithreaded execution, based on native operating system threads of
   112   the underlying platform.  Thus threads will actually be executed in
   113   parallel on multi-core systems.  A speedup-factor of approximately
   114   1.5--3 can be expected on a regular 4-core machine.\footnote{There
   115   is some inherent limitation of the speedup factor due to garbage
   116   collection, which is still sequential.  It helps to provide initial
   117   heap space generously, using the \texttt{-H} option of Poly/ML.}
   118   Threads also help to organize advanced operations of the system,
   119   with explicit communication between sub-components, real-time
   120   conditions, time-outs etc.
   121 
   122   Threads lack the memory protection of separate processes, and
   123   operate concurrently on shared heap memory.  This has the advantage
   124   that results of independent computations are immediately available
   125   to other threads, without requiring untyped character streams,
   126   awkward serialization etc.
   127 
   128   On the other hand, some programming guidelines need to be observed
   129   in order to make unprotected parallelism work out smoothly.  While
   130   the ML system implementation is responsible to maintain basic
   131   integrity of the representation of ML values in memory, the
   132   application programmer needs to ensure that multithreaded execution
   133   does not break the intended semantics.
   134 
   135   \medskip \paragraph{Critical shared resources.} Actually only those
   136   parts outside the purely functional world of ML are critical.  In
   137   particular, this covers
   138 
   139   \begin{itemize}
   140 
   141   \item global references (or arrays), i.e.\ those that persist over
   142   several invocations of associated operations,\footnote{This is
   143   independent of the visibility of such mutable values in the toplevel
   144   scope.}
   145 
   146   \item direct I/O on shared channels, notably @{text "stdin"}, @{text
   147   "stdout"}, @{text "stderr"}.
   148 
   149   \end{itemize}
   150 
   151   The majority of tools implemented within the Isabelle/Isar framework
   152   will not require any of these critical elements: nothing special
   153   needs to be observed when staying in the purely functional fragment
   154   of ML.  Note that output via the official Isabelle channels does not
   155   count as direct I/O, so the operations @{ML "writeln"}, @{ML
   156   "warning"}, @{ML "tracing"} etc.\ are safe.
   157 
   158   Moreover, ML bindings within the toplevel environment (@{verbatim
   159   "type"}, @{verbatim val}, @{verbatim "structure"} etc.) due to
   160   run-time invocation of the compiler are also safe, because
   161   Isabelle/Isar manages this as part of the theory or proof context.
   162 
   163   \paragraph{Multithreading in Isabelle/Isar.}  The theory loader
   164   automatically exploits the overall parallelism of independent nodes
   165   in the development graph, as well as the inherent irrelevance of
   166   proofs for goals being fully specified in advance.  This means,
   167   checking of individual Isar proofs is parallelized by default.
   168   Beyond that, very sophisticated proof tools may use local
   169   parallelism internally, via the general programming model of
   170   ``future values'' (see also @{"file"
   171   "~~/src/Pure/Concurrent/future.ML"}).
   172 
   173   Any ML code that works relatively to the present background theory
   174   is already safe.  Contextual data may be easily stored within the
   175   theory or proof context, thanks to the generic data concept of
   176   Isabelle/Isar (see \secref{sec:context-data}).  This greatly
   177   diminishes the demand for global state information in the first
   178   place.
   179 
   180   \medskip In rare situations where actual mutable content needs to be
   181   manipulated, Isabelle provides a single \emph{critical section} that
   182   may be entered while preventing any other thread from doing the
   183   same.  Entering the critical section without contention is very
   184   fast, and several basic system operations do so frequently.  This
   185   also means that each thread should leave the critical section
   186   quickly, otherwise parallel execution performance may degrade
   187   significantly.
   188 
   189   Despite this potential bottle-neck, centralized locking is
   190   convenient, because it prevents deadlocks without demanding special
   191   precautions.  Explicit communication demands other means, though.
   192   The high-level abstraction of synchronized variables @{"file"
   193   "~~/src/Pure/Concurrent/synchronized.ML"} enables parallel
   194   components to communicate via shared state; see also @{"file"
   195   "~~/src/Pure/Concurrent/mailbox.ML"} as canonical example.
   196 
   197   \paragraph{Good conduct of impure programs.} The following
   198   guidelines enable non-functional programs to participate in
   199   multithreading.
   200 
   201   \begin{itemize}
   202 
   203   \item Minimize global state information.  Using proper theory and
   204   proof context data will actually return to functional update of
   205   values, without any special precautions for multithreading.  Apart
   206   from the fully general functors for theory and proof data (see
   207   \secref{sec:context-data}) there are drop-in replacements that
   208   emulate primitive references for common cases of \emph{configuration
   209   options} for type @{ML_type "bool"}/@{ML_type "int"}/@{ML_type
   210   "string"} (see structure @{ML_struct Config} and @{ML
   211   Attrib.config_bool} etc.), and lists of theorems (see functor
   212   @{ML_functor Named_Thms}).
   213 
   214   \item Keep components with local state information
   215   \emph{re-entrant}.  Instead of poking initial values into (private)
   216   global references, create a new state record on each invocation, and
   217   pass that through any auxiliary functions of the component.  The
   218   state record may well contain mutable references, without requiring
   219   any special synchronizations, as long as each invocation sees its
   220   own copy.  Occasionally, one might even return to plain functional
   221   updates on non-mutable record values here.
   222 
   223   \item Isolate process configuration flags.  The main legitimate
   224   application of global references is to configure the whole process
   225   in a certain way, essentially affecting all threads.  A typical
   226   example is the @{ML show_types} flag, which tells the pretty printer
   227   to output explicit type information for terms.  Such flags usually
   228   do not affect the functionality of the core system, but only the
   229   view being presented to the user.
   230 
   231   Occasionally, such global process flags are treated like implicit
   232   arguments to certain operations, by using the @{ML setmp_CRITICAL} combinator
   233   for safe temporary assignment.  Its traditional purpose was to
   234   ensure proper recovery of the original value when exceptions are
   235   raised in the body, now the functionality is extended to enter the
   236   \emph{critical section} (with its usual potential of degrading
   237   parallelism).
   238 
   239   Note that recovery of plain value passing semantics via @{ML
   240   setmp_CRITICAL}~@{text "ref value"} assumes that this @{text "ref"} is
   241   exclusively manipulated within the critical section.  In particular,
   242   any persistent global assignment of @{text "ref := value"} needs to
   243   be marked critical as well, to prevent intruding another threads
   244   local view, and a lost-update in the global scope, too.
   245 
   246   \end{itemize}
   247 
   248   Recall that in an open ``LCF-style'' system like Isabelle/Isar, the
   249   user participates in constructing the overall environment.  This
   250   means that state-based facilities offered by one component will
   251   require special caution later on.  So minimizing critical elements,
   252   by staying within the plain value-oriented view relative to theory
   253   or proof contexts most of the time, will also reduce the chance of
   254   mishaps occurring to end-users.
   255 *}
   256 
   257 text %mlref {*
   258   \begin{mldecls}
   259   @{index_ML NAMED_CRITICAL: "string -> (unit -> 'a) -> 'a"} \\
   260   @{index_ML CRITICAL: "(unit -> 'a) -> 'a"} \\
   261   @{index_ML setmp_CRITICAL: "'a Unsynchronized.ref -> 'a -> ('b -> 'c) -> 'b -> 'c"} \\
   262   \end{mldecls}
   263 
   264   \begin{description}
   265 
   266   \item @{ML NAMED_CRITICAL}~@{text "name f"} evaluates @{text "f ()"}
   267   while staying within the critical section of Isabelle/Isar.  No
   268   other thread may do so at the same time, but non-critical parallel
   269   execution will continue.  The @{text "name"} argument serves for
   270   diagnostic purposes and might help to spot sources of congestion.
   271 
   272   \item @{ML CRITICAL} is the same as @{ML NAMED_CRITICAL} with empty
   273   name argument.
   274 
   275   \item @{ML setmp_CRITICAL}~@{text "ref value f x"} evaluates @{text "f x"}
   276   while staying within the critical section and having @{text "ref :=
   277   value"} assigned temporarily.  This recovers a value-passing
   278   semantics involving global references, regardless of exceptions or
   279   concurrency.
   280 
   281   \end{description}
   282 *}
   283 
   284 
   285 chapter {* Basic library functions *}
   286 
   287 text {*
   288   Beyond the proposal of the SML/NJ basis library, Isabelle comes
   289   with its own library, from which selected parts are given here.
   290   These should encourage a study of the Isabelle sources,
   291   in particular files \emph{Pure/library.ML} and \emph{Pure/General/*.ML}.
   292 *}
   293 
   294 section {* Linear transformations \label{sec:ML-linear-trans} *}
   295 
   296 text %mlref {*
   297   \begin{mldecls}
   298   @{index_ML "op |> ": "'a * ('a -> 'b) -> 'b"} \\
   299   \end{mldecls}
   300 *}
   301 
   302 (*<*)
   303 typedecl foo
   304 consts foo :: foo
   305 ML {*
   306 val thy = Theory.copy @{theory}
   307 *}
   308 (*>*)
   309 
   310 text {*
   311   \noindent Many problems in functional programming can be thought of
   312   as linear transformations, i.e.~a caluclation starts with a
   313   particular value @{ML_text "x : foo"} which is then transformed
   314   by application of a function @{ML_text "f : foo -> foo"},
   315   continued by an application of a function @{ML_text "g : foo -> bar"},
   316   and so on.  As a canoncial example, take functions enriching
   317   a theory by constant declararion and primitive definitions:
   318 
   319   \smallskip\begin{mldecls}
   320   @{ML "Sign.declare_const: (binding * typ) * mixfix
   321   -> theory -> term * theory"} \\
   322   @{ML "Thm.add_def: bool -> bool -> binding * term -> theory -> (string * thm) * theory"}
   323   \end{mldecls}
   324 
   325   \noindent Written with naive application, an addition of constant
   326   @{term bar} with type @{typ "foo \<Rightarrow> foo"} and
   327   a corresponding definition @{term "bar \<equiv> \<lambda>x. x"} would look like:
   328 
   329   \smallskip\begin{mldecls}
   330   @{ML "(fn (t, thy) => Thm.add_def false false
   331   (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})) thy)
   332     (Sign.declare_const
   333       ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn) thy)"}
   334   \end{mldecls}
   335 
   336   \noindent With increasing numbers of applications, this code gets quite
   337   unreadable.  Further, it is unintuitive that things are
   338   written down in the opposite order as they actually ``happen''.
   339 *}
   340 
   341 text {*
   342   \noindent At this stage, Isabelle offers some combinators which allow
   343   for more convenient notation, most notably reverse application:
   344 
   345   \smallskip\begin{mldecls}
   346 @{ML "thy
   347 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   348 |> (fn (t, thy) => thy
   349 |> Thm.add_def false false
   350      (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})))"}
   351   \end{mldecls}
   352 *}
   353 
   354 text %mlref {*
   355   \begin{mldecls}
   356   @{index_ML "op |-> ": "('c * 'a) * ('c -> 'a -> 'b) -> 'b"} \\
   357   @{index_ML "op |>> ": "('a * 'c) * ('a -> 'b) -> 'b * 'c"} \\
   358   @{index_ML "op ||> ": "('c * 'a) * ('a -> 'b) -> 'c * 'b"} \\
   359   @{index_ML "op ||>> ": "('c * 'a) * ('a -> 'd * 'b) -> ('c * 'd) * 'b"} \\
   360   \end{mldecls}
   361 *}
   362 
   363 text {*
   364   \noindent Usually, functions involving theory updates also return
   365   side results; to use these conveniently, yet another
   366   set of combinators is at hand, most notably @{ML "op |->"}
   367   which allows curried access to side results:
   368 
   369   \smallskip\begin{mldecls}
   370 @{ML "thy
   371 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   372 |-> (fn t => Thm.add_def false false
   373       (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})))
   374 "}
   375   \end{mldecls}
   376 
   377   \noindent @{ML "op |>>"} allows for processing side results on their own:
   378 
   379   \smallskip\begin{mldecls}
   380 @{ML "thy
   381 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   382 |>> (fn t => Logic.mk_equals (t, @{term \"%x. x\"}))
   383 |-> (fn def => Thm.add_def false false (Binding.name \"bar_def\", def))
   384 "}
   385   \end{mldecls}
   386 
   387   \noindent Orthogonally, @{ML "op ||>"} applies a transformation
   388   in the presence of side results which are left unchanged:
   389 
   390   \smallskip\begin{mldecls}
   391 @{ML "thy
   392 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   393 ||> Sign.add_path \"foobar\"
   394 |-> (fn t => Thm.add_def false false
   395       (Binding.name \"bar_def\", Logic.mk_equals (t, @{term \"%x. x\"})))
   396 ||> Sign.restore_naming thy
   397 "}
   398   \end{mldecls}
   399 
   400   \noindent @{ML "op ||>>"} accumulates side results:
   401 
   402   \smallskip\begin{mldecls}
   403 @{ML "thy
   404 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   405 ||>> Sign.declare_const ((Binding.name \"foobar\", @{typ \"foo => foo\"}), NoSyn)
   406 |-> (fn (t1, t2) => Thm.add_def false false
   407       (Binding.name \"bar_def\", Logic.mk_equals (t1, t2)))
   408 "}
   409   \end{mldecls}
   410 *}
   411 
   412 text %mlref {*
   413   \begin{mldecls}
   414   @{index_ML fold: "('a -> 'b -> 'b) -> 'a list -> 'b -> 'b"} \\
   415   @{index_ML fold_map: "('a -> 'b -> 'c * 'b) -> 'a list -> 'b -> 'c list * 'b"} \\
   416   \end{mldecls}
   417 *}
   418 
   419 text {*
   420   \noindent This principles naturally lift to \emph{lists} using
   421   the @{ML fold} and @{ML fold_map} combinators.
   422   The first lifts a single function
   423   \begin{quote}\footnotesize
   424     @{ML_text "f : 'a -> 'b -> 'b"} to @{ML_text "'a list -> 'b -> 'b"}
   425   \end{quote}
   426   such that
   427   \begin{quote}\footnotesize
   428     @{ML_text "y |> fold f [x1, x2, ..., x_n]"} \\
   429     \hspace*{2ex}@{text "\<leadsto>"} @{ML_text "y |> f x1 |> f x2 |> ... |> f x_n"}
   430   \end{quote}
   431   \noindent The second accumulates side results in a list by lifting
   432   a single function
   433   \begin{quote}\footnotesize
   434     @{ML_text "f : 'a -> 'b -> 'c * 'b"} to @{ML_text "'a list -> 'b -> 'c list * 'b"}
   435   \end{quote}
   436   such that
   437   \begin{quote}\footnotesize
   438     @{ML_text "y |> fold_map f [x1, x2, ..., x_n]"} \\
   439     \hspace*{2ex}@{text "\<leadsto>"} @{ML_text "y |> f x1 ||>> f x2 ||>> ... ||>> f x_n"} \\
   440     \hspace*{6ex}@{ML_text "||> (fn ((z1, z2), ..., z_n) => [z1, z2, ..., z_n])"}
   441   \end{quote}
   442   
   443   \noindent Example:
   444 
   445   \smallskip\begin{mldecls}
   446 @{ML "let
   447   val consts = [\"foo\", \"bar\"];
   448 in
   449   thy
   450   |> fold_map (fn const => Sign.declare_const
   451        ((Binding.name const, @{typ \"foo => foo\"}), NoSyn)) consts
   452   |>> map (fn t => Logic.mk_equals (t, @{term \"%x. x\"}))
   453   |-> (fn defs => fold_map (fn def =>
   454        Thm.add_def false false (Binding.empty, def)) defs)
   455 end"}
   456   \end{mldecls}
   457 *}
   458 
   459 text %mlref {*
   460   \begin{mldecls}
   461   @{index_ML "op #> ": "('a -> 'b) * ('b -> 'c) -> 'a -> 'c"} \\
   462   @{index_ML "op #-> ": "('a -> 'c * 'b) * ('c -> 'b -> 'd) -> 'a -> 'd"} \\
   463   @{index_ML "op #>> ": "('a -> 'c * 'b) * ('c -> 'd) -> 'a -> 'd * 'b"} \\
   464   @{index_ML "op ##> ": "('a -> 'c * 'b) * ('b -> 'd) -> 'a -> 'c * 'd"} \\
   465   @{index_ML "op ##>> ": "('a -> 'c * 'b) * ('b -> 'e * 'd) -> 'a -> ('c * 'e) * 'd"} \\
   466   \end{mldecls}
   467 *}
   468 
   469 text {*
   470   \noindent All those linear combinators also exist in higher-order
   471   variants which do not expect a value on the left hand side
   472   but a function.
   473 *}
   474 
   475 text %mlref {*
   476   \begin{mldecls}
   477   @{index_ML "op ` ": "('b -> 'a) -> 'b -> 'a * 'b"} \\
   478   @{index_ML tap: "('b -> 'a) -> 'b -> 'b"} \\
   479   \end{mldecls}
   480 *}
   481 
   482 text {*
   483   \noindent These operators allow to ``query'' a context
   484   in a series of context transformations:
   485 
   486   \smallskip\begin{mldecls}
   487 @{ML "thy
   488 |> tap (fn _ => writeln \"now adding constant\")
   489 |> Sign.declare_const ((Binding.name \"bar\", @{typ \"foo => foo\"}), NoSyn)
   490 ||>> `(fn thy => Sign.declared_const thy
   491          (Sign.full_name thy (Binding.name \"foobar\")))
   492 |-> (fn (t, b) => if b then I
   493        else Sign.declare_const
   494          ((Binding.name \"foobar\", @{typ \"foo => foo\"}), NoSyn) #> snd)
   495 "}
   496   \end{mldecls}
   497 *}
   498 
   499 section {* Options and partiality *}
   500 
   501 text %mlref {*
   502   \begin{mldecls}
   503   @{index_ML is_some: "'a option -> bool"} \\
   504   @{index_ML is_none: "'a option -> bool"} \\
   505   @{index_ML the: "'a option -> 'a"} \\
   506   @{index_ML these: "'a list option -> 'a list"} \\
   507   @{index_ML the_list: "'a option -> 'a list"} \\
   508   @{index_ML the_default: "'a -> 'a option -> 'a"} \\
   509   @{index_ML try: "('a -> 'b) -> 'a -> 'b option"} \\
   510   @{index_ML can: "('a -> 'b) -> 'a -> bool"} \\
   511   \end{mldecls}
   512 *}
   513 
   514 text {*
   515   Standard selector functions on @{text option}s are provided.  The
   516   @{ML try} and @{ML can} functions provide a convenient interface for
   517   handling exceptions -- both take as arguments a function @{ML_text f}
   518   together with a parameter @{ML_text x} and handle any exception during
   519   the evaluation of the application of @{ML_text f} to @{ML_text x}, either
   520   return a lifted result (@{ML NONE} on failure) or a boolean value
   521   (@{ML false} on failure).
   522 *}
   523 
   524 
   525 section {* Common data structures *}
   526 
   527 subsection {* Lists (as set-like data structures) *}
   528 
   529 text {*
   530   \begin{mldecls}
   531   @{index_ML member: "('b * 'a -> bool) -> 'a list -> 'b -> bool"} \\
   532   @{index_ML insert: "('a * 'a -> bool) -> 'a -> 'a list -> 'a list"} \\
   533   @{index_ML remove: "('b * 'a -> bool) -> 'b -> 'a list -> 'a list"} \\
   534   @{index_ML merge: "('a * 'a -> bool) -> 'a list * 'a list -> 'a list"} \\
   535   \end{mldecls}
   536 *}
   537 
   538 text {*
   539   Lists are often used as set-like data structures -- set-like in
   540   the sense that they support a notion of @{ML member}-ship,
   541   @{ML insert}-ing and @{ML remove}-ing, but are order-sensitive.
   542   This is convenient when implementing a history-like mechanism:
   543   @{ML insert} adds an element \emph{to the front} of a list,
   544   if not yet present; @{ML remove} removes \emph{all} occurences
   545   of a particular element.  Correspondingly @{ML merge} implements a 
   546   a merge on two lists suitable for merges of context data
   547   (\secref{sec:context-theory}).
   548 
   549   Functions are parametrized by an explicit equality function
   550   to accomplish overloaded equality;  in most cases of monomorphic
   551   equality, writing @{ML "op ="} should suffice.
   552 *}
   553 
   554 subsection {* Association lists *}
   555 
   556 text {*
   557   \begin{mldecls}
   558   @{index_ML_exn AList.DUP} \\
   559   @{index_ML AList.lookup: "('a * 'b -> bool) -> ('b * 'c) list -> 'a -> 'c option"} \\
   560   @{index_ML AList.defined: "('a * 'b -> bool) -> ('b * 'c) list -> 'a -> bool"} \\
   561   @{index_ML AList.update: "('a * 'a -> bool) -> ('a * 'b) -> ('a * 'b) list -> ('a * 'b) list"} \\
   562   @{index_ML AList.default: "('a * 'a -> bool) -> ('a * 'b) -> ('a * 'b) list -> ('a * 'b) list"} \\
   563   @{index_ML AList.delete: "('a * 'b -> bool) -> 'a -> ('b * 'c) list -> ('b * 'c) list"} \\
   564   @{index_ML AList.map_entry: "('a * 'b -> bool) -> 'a
   565     -> ('c -> 'c) -> ('b * 'c) list -> ('b * 'c) list"} \\
   566   @{index_ML AList.map_default: "('a * 'a -> bool) -> 'a * 'b -> ('b -> 'b)
   567     -> ('a * 'b) list -> ('a * 'b) list"} \\
   568   @{index_ML AList.join: "('a * 'a -> bool) -> ('a -> 'b * 'b -> 'b) (*exception DUP*)
   569     -> ('a * 'b) list * ('a * 'b) list -> ('a * 'b) list (*exception AList.DUP*)"} \\
   570   @{index_ML AList.merge: "('a * 'a -> bool) -> ('b * 'b -> bool)
   571     -> ('a * 'b) list * ('a * 'b) list -> ('a * 'b) list (*exception AList.DUP*)"}
   572   \end{mldecls}
   573 *}
   574 
   575 text {*
   576   Association lists can be seens as an extension of set-like lists:
   577   on the one hand, they may be used to implement finite mappings,
   578   on the other hand, they remain order-sensitive and allow for
   579   multiple key-value-pair with the same key: @{ML AList.lookup}
   580   returns the \emph{first} value corresponding to a particular
   581   key, if present.  @{ML AList.update} updates
   582   the \emph{first} occurence of a particular key; if no such
   583   key exists yet, the key-value-pair is added \emph{to the front}.
   584   @{ML AList.delete} only deletes the \emph{first} occurence of a key.
   585   @{ML AList.merge} provides an operation suitable for merges of context data
   586   (\secref{sec:context-theory}), where an equality parameter on
   587   values determines whether a merge should be considered a conflict.
   588   A slightly generalized operation if implementend by the @{ML AList.join}
   589   function which allows for explicit conflict resolution.
   590 *}
   591 
   592 subsection {* Tables *}
   593 
   594 text {*
   595   \begin{mldecls}
   596   @{index_ML_type "'a Symtab.table"} \\
   597   @{index_ML_exn Symtab.DUP: string} \\
   598   @{index_ML_exn Symtab.SAME} \\
   599   @{index_ML_exn Symtab.UNDEF: string} \\
   600   @{index_ML Symtab.empty: "'a Symtab.table"} \\
   601   @{index_ML Symtab.lookup: "'a Symtab.table -> string -> 'a option"} \\
   602   @{index_ML Symtab.defined: "'a Symtab.table -> string -> bool"} \\
   603   @{index_ML Symtab.update: "(string * 'a) -> 'a Symtab.table -> 'a Symtab.table"} \\
   604   @{index_ML Symtab.default: "string * 'a -> 'a Symtab.table -> 'a Symtab.table"} \\
   605   @{index_ML Symtab.delete: "string
   606     -> 'a Symtab.table -> 'a Symtab.table (*exception Symtab.UNDEF*)"} \\
   607   @{index_ML Symtab.map_entry: "string -> ('a -> 'a)
   608     -> 'a Symtab.table -> 'a Symtab.table"} \\
   609   @{index_ML Symtab.map_default: "(string * 'a) -> ('a -> 'a)
   610     -> 'a Symtab.table -> 'a Symtab.table"} \\
   611   @{index_ML Symtab.join: "(string -> 'a * 'a -> 'a) (*exception Symtab.DUP/Symtab.SAME*)
   612     -> 'a Symtab.table * 'a Symtab.table
   613     -> 'a Symtab.table (*exception Symtab.DUP*)"} \\
   614   @{index_ML Symtab.merge: "('a * 'a -> bool)
   615     -> 'a Symtab.table * 'a Symtab.table
   616     -> 'a Symtab.table (*exception Symtab.DUP*)"}
   617   \end{mldecls}
   618 *}
   619 
   620 text {*
   621   Tables are an efficient representation of finite mappings without
   622   any notion of order;  due to their efficiency they should be used
   623   whenever such pure finite mappings are neccessary.
   624 
   625   The key type of tables must be given explicitly by instantiating
   626   the @{ML_functor Table} functor which takes the key type
   627   together with its @{ML_type order}; for convience, we restrict
   628   here to the @{ML_struct Symtab} instance with @{ML_type string}
   629   as key type.
   630 
   631   Most table functions correspond to those of association lists.
   632 *}
   633 
   634 end