aboutsummaryrefslogtreecommitdiffhomepage
path: root/doc/sphinx/addendum
diff options
context:
space:
mode:
authorGravatar Matthieu Sozeau <mattam@mattam.org>2018-03-24 14:00:37 -0300
committerGravatar Matthieu Sozeau <mattam@mattam.org>2018-03-26 12:09:16 -0300
commit2e24b82ced473fa5b8f9671407fcc8a8712fe946 (patch)
tree358808090187a95bba1569646ad66a34a8affad2 /doc/sphinx/addendum
parent4e3819425445c3236f6aca77e95f2ee854cf4417 (diff)
Move Classes.tex to type-classes.rst
Diffstat (limited to 'doc/sphinx/addendum')
-rw-r--r--doc/sphinx/addendum/type-classes.rst578
1 files changed, 578 insertions, 0 deletions
diff --git a/doc/sphinx/addendum/type-classes.rst b/doc/sphinx/addendum/type-classes.rst
new file mode 100644
index 000000000..da798a238
--- /dev/null
+++ b/doc/sphinx/addendum/type-classes.rst
@@ -0,0 +1,578 @@
+\def\Haskell{\textsc{Haskell}\xspace}
+\def\eol{\setlength\parskip{0pt}\par}
+\def\indent#1{\noindent\kern#1}
+\def\cst#1{\textsf{#1}}
+
+\newcommand\tele[1]{\overrightarrow{#1}}
+
+\achapter{\protect{Type Classes}}
+%HEVEA\cutname{type-classes.html}
+\aauthor{Matthieu Sozeau}
+\label{typeclasses}
+
+This chapter presents a quick reference of the commands related to type
+classes. For an actual introduction to type classes, there is a
+description of the system \cite{sozeau08} and the literature on type
+classes in \Haskell which also applies.
+
+\asection{Class and Instance declarations}
+\label{ClassesInstances}
+
+The syntax for class and instance declarations is the same as
+record syntax of \Coq:
+\def\kw{\texttt}
+\def\classid{\texttt}
+
+\begin{center}
+\[\begin{array}{l}
+\kw{Class}~\classid{Id}~(\alpha_1 : \tau_1) \cdots (\alpha_n : \tau_n)
+[: \sort] := \{\\
+\begin{array}{p{0em}lcl}
+ & \cst{f}_1 & : & \type_1 ; \\
+ & \vdots & & \\
+ & \cst{f}_m & : & \type_m \}.
+\end{array}\end{array}\]
+\end{center}
+\begin{center}
+\[\begin{array}{l}
+\kw{Instance}~\ident~:~\classid{Id}~\term_1 \cdots \term_n := \{\\
+\begin{array}{p{0em}lcl}
+ & \cst{f}_1 & := & \term_{f_1} ; \\
+ & \vdots & & \\
+ & \cst{f}_m & := & \term_{f_m} \}.
+\end{array}\end{array}\]
+\end{center}
+\begin{coq_eval}
+ Reset Initial.
+ Generalizable All Variables.
+\end{coq_eval}
+
+The $\tele{\alpha_i : \tau_i}$ variables are called the \emph{parameters}
+of the class and the $\tele{f_k : \type_k}$ are called the
+\emph{methods}. Each class definition gives rise to a corresponding
+record declaration and each instance is a regular definition whose name
+is given by $\ident$ and type is an instantiation of the record type.
+
+We'll use the following example class in the rest of the chapter:
+
+\begin{coq_example*}
+Class EqDec (A : Type) := {
+ eqb : A -> A -> bool ;
+ eqb_leibniz : forall x y, eqb x y = true -> x = y }.
+\end{coq_example*}
+
+This class implements a boolean equality test which is compatible with
+Leibniz equality on some type. An example implementation is:
+
+\begin{coq_example*}
+Instance unit_EqDec : EqDec unit :=
+{ eqb x y := true ;
+ eqb_leibniz x y H :=
+ match x, y return x = y with tt, tt => eq_refl tt end }.
+\end{coq_example*}
+
+If one does not give all the members in the \texttt{Instance}
+declaration, Coq enters the proof-mode and the user is asked to build
+inhabitants of the remaining fields, e.g.:
+
+\begin{coq_example*}
+Instance eq_bool : EqDec bool :=
+{ eqb x y := if x then y else negb y }.
+\end{coq_example*}
+\begin{coq_example}
+Proof. intros x y H.
+ destruct x ; destruct y ; (discriminate || reflexivity).
+Defined.
+\end{coq_example}
+
+One has to take care that the transparency of every field is determined
+by the transparency of the \texttt{Instance} proof. One can use
+alternatively the \texttt{Program} \texttt{Instance} \comindex{Program Instance} variant which has
+richer facilities for dealing with obligations.
+
+\asection{Binding classes}
+
+Once a type class is declared, one can use it in class binders:
+\begin{coq_example}
+Definition neqb {A} {eqa : EqDec A} (x y : A) := negb (eqb x y).
+\end{coq_example}
+
+When one calls a class method, a constraint is generated that is
+satisfied only in contexts where the appropriate instances can be
+found. In the example above, a constraint \texttt{EqDec A} is generated and
+satisfied by \texttt{{eqa : EqDec A}}. In case no satisfying constraint can be
+found, an error is raised:
+
+\begin{coq_example}
+Fail Definition neqb' (A : Type) (x y : A) := negb (eqb x y).
+\end{coq_example}
+
+The algorithm used to solve constraints is a variant of the eauto tactic
+that does proof search with a set of lemmas (the instances). It will use
+local hypotheses as well as declared lemmas in the
+\texttt{typeclass\_instances} database. Hence the example can also be
+written:
+
+\begin{coq_example}
+Definition neqb' A (eqa : EqDec A) (x y : A) := negb (eqb x y).
+\end{coq_example}
+
+However, the generalizing binders should be used instead as they have
+particular support for type classes:
+\begin{itemize}
+\item They automatically set the maximally implicit status for type
+ class arguments, making derived functions as easy to use as class
+ methods. In the example above, \texttt{A} and \texttt{eqa} should be
+ set maximally implicit.
+\item They support implicit quantification on partially applied type
+ classes (\S \ref{implicit-generalization}).
+ Any argument not given as part of a type class binder will be
+ automatically generalized.
+\item They also support implicit quantification on superclasses
+ (\S \ref{classes:superclasses})
+\end{itemize}
+
+Following the previous example, one can write:
+\begin{coq_example}
+Definition neqb_impl `{eqa : EqDec A} (x y : A) := negb (eqb x y).
+\end{coq_example}
+
+Here \texttt{A} is implicitly generalized, and the resulting function
+is equivalent to the one above.
+
+\asection{Parameterized Instances}
+
+One can declare parameterized instances as in \Haskell simply by giving
+the constraints as a binding context before the instance, e.g.:
+
+\begin{coq_example}
+Instance prod_eqb `(EA : EqDec A, EB : EqDec B) : EqDec (A * B) :=
+{ eqb x y := match x, y with
+ | (la, ra), (lb, rb) => andb (eqb la lb) (eqb ra rb)
+ end }.
+\end{coq_example}
+\begin{coq_eval}
+Admitted.
+\end{coq_eval}
+
+These instances are used just as well as lemmas in the instance hint database.
+
+\asection{Sections and contexts}
+\label{SectionContext}
+To ease the parametrization of developments by type classes, we provide
+a new way to introduce variables into section contexts, compatible with
+the implicit argument mechanism.
+The new command works similarly to the \texttt{Variables} vernacular
+(see \ref{Variable}), except it accepts any binding context as argument.
+For example:
+
+\begin{coq_example}
+Section EqDec_defs.
+ Context `{EA : EqDec A}.
+\end{coq_example}
+
+\begin{coq_example*}
+ Global Instance option_eqb : EqDec (option A) :=
+ { eqb x y := match x, y with
+ | Some x, Some y => eqb x y
+ | None, None => true
+ | _, _ => false
+ end }.
+\end{coq_example*}
+\begin{coq_eval}
+Proof.
+intros x y ; destruct x ; destruct y ; intros H ;
+try discriminate ; try apply eqb_leibniz in H ;
+subst ; auto.
+Defined.
+\end{coq_eval}
+
+\begin{coq_example}
+End EqDec_defs.
+About option_eqb.
+\end{coq_example}
+
+Here the \texttt{Global} modifier redeclares the instance at the end of
+the section, once it has been generalized by the context variables it uses.
+
+\asection{Building hierarchies}
+
+\subsection{Superclasses}
+\label{classes:superclasses}
+One can also parameterize classes by other classes, generating a
+hierarchy of classes and superclasses. In the same way, we give the
+superclasses as a binding context:
+
+\begin{coq_example*}
+Class Ord `(E : EqDec A) :=
+ { le : A -> A -> bool }.
+\end{coq_example*}
+
+Contrary to \Haskell, we have no special syntax for superclasses, but
+this declaration is morally equivalent to:
+\begin{verbatim}
+Class `(E : EqDec A) => Ord A :=
+ { le : A -> A -> bool }.
+\end{verbatim}
+
+This declaration means that any instance of the \texttt{Ord} class must
+have an instance of \texttt{EqDec}. The parameters of the subclass contain
+at least all the parameters of its superclasses in their order of
+appearance (here \texttt{A} is the only one).
+As we have seen, \texttt{Ord} is encoded as a record type with two parameters:
+a type \texttt{A} and an \texttt{E} of type \texttt{EqDec A}. However, one can
+still use it as if it had a single parameter inside generalizing binders: the
+generalization of superclasses will be done automatically.
+\begin{coq_example*}
+Definition le_eqb `{Ord A} (x y : A) := andb (le x y) (le y x).
+\end{coq_example*}
+
+In some cases, to be able to specify sharing of structures, one may want to give
+explicitly the superclasses. It is is possible to do it directly in regular
+binders, and using the \texttt{!} modifier in class binders. For
+example:
+\begin{coq_example*}
+Definition lt `{eqa : EqDec A, ! Ord eqa} (x y : A) :=
+ andb (le x y) (neqb x y).
+\end{coq_example*}
+
+The \texttt{!} modifier switches the way a binder is parsed back to the
+regular interpretation of Coq. In particular, it uses the implicit
+arguments mechanism if available, as shown in the example.
+
+\subsection{Substructures}
+
+Substructures are components of a class which are instances of a class
+themselves. They often arise when using classes for logical properties,
+e.g.:
+
+\begin{coq_eval}
+Require Import Relations.
+\end{coq_eval}
+\begin{coq_example*}
+Class Reflexive (A : Type) (R : relation A) :=
+ reflexivity : forall x, R x x.
+Class Transitive (A : Type) (R : relation A) :=
+ transitivity : forall x y z, R x y -> R y z -> R x z.
+\end{coq_example*}
+
+This declares singleton classes for reflexive and transitive relations,
+(see \ref{SingletonClass} for an explanation).
+These may be used as part of other classes:
+
+\begin{coq_example*}
+Class PreOrder (A : Type) (R : relation A) :=
+{ PreOrder_Reflexive :> Reflexive A R ;
+ PreOrder_Transitive :> Transitive A R }.
+\end{coq_example*}
+
+The syntax \texttt{:>} indicates that each \texttt{PreOrder} can be seen
+as a \texttt{Reflexive} relation. So each time a reflexive relation is
+needed, a preorder can be used instead. This is very similar to the
+coercion mechanism of \texttt{Structure} declarations.
+The implementation simply declares each projection as an instance.
+
+One can also declare existing objects or structure
+projections using the \texttt{Existing Instance} command to achieve the
+same effect.
+
+\section{Summary of the commands
+\label{TypeClassCommands}}
+
+\subsection{\tt Class {\ident} {\binder$_1$ \ldots~\binder$_n$}
+ : \sort := \{ field$_1$ ; \ldots ; field$_k$ \}.}
+\comindex{Class}
+\label{Class}
+
+The \texttt{Class} command is used to declare a type class with
+parameters {\binder$_1$} to {\binder$_n$} and fields {\tt field$_1$} to
+{\tt field$_k$}.
+
+\begin{Variants}
+\item \label{SingletonClass} {\tt Class {\ident} {\binder$_1$ \ldots \binder$_n$}
+ : \sort := \ident$_1$ : \type$_1$.}
+ This variant declares a \emph{singleton} class whose only method is
+ {\tt \ident$_1$}. This singleton class is a so-called definitional
+ class, represented simply as a definition
+ {\tt {\ident} \binder$_1$ \ldots \binder$_n$ := \type$_1$} and whose
+ instances are themselves objects of this type. Definitional classes
+ are not wrapped inside records, and the trivial projection of an
+ instance of such a class is convertible to the instance itself. This can
+ be useful to make instances of existing objects easily and to reduce
+ proof size by not inserting useless projections. The class
+ constant itself is declared rigid during resolution so that the class
+ abstraction is maintained.
+
+\item \label{ExistingClass} {\tt Existing Class {\ident}.\comindex{Existing Class}}
+ This variant declares a class a posteriori from a constant or
+ inductive definition. No methods or instances are defined.
+\end{Variants}
+
+\subsection{\tt Instance {\ident} {\binder$_1$ \ldots \binder$_n$} :
+ {Class} {t$_1$ \ldots t$_n$} [| \textit{priority}]
+ := \{ field$_1$ := b$_1$ ; \ldots ; field$_i$ := b$_i$ \}}
+\comindex{Instance}
+\label{Instance}
+
+The \texttt{Instance} command is used to declare a type class instance
+named {\ident} of the class \emph{Class} with parameters {t$_1$} to {t$_n$} and
+fields {\tt b$_1$} to {\tt b$_i$}, where each field must be a declared
+field of the class. Missing fields must be filled in interactive proof mode.
+
+An arbitrary context of the form {\tt \binder$_1$ \ldots \binder$_n$}
+can be put after the name of the instance and before the colon to
+declare a parameterized instance.
+An optional \textit{priority} can be declared, 0 being the highest
+priority as for auto hints. If the priority is not specified, it defaults to
+$n$, the number of binders of the instance.
+
+\begin{Variants}
+\item {\tt Instance {\ident} {\binder$_1$ \ldots \binder$_n$} :
+ forall {\binder$_{n+1}$ \ldots \binder$_m$},
+ {Class} {t$_1$ \ldots t$_n$} [| \textit{priority}] := \term}
+ This syntax is used for declaration of singleton class instances or
+ for directly giving an explicit term of type
+ {\tt forall {\binder$_{n+1}$ \ldots \binder$_m$}, {Class} {t$_1$ \ldots t$_n$}}.
+ One need not even mention the unique field name for singleton classes.
+
+\item {\tt Global Instance} One can use the \texttt{Global} modifier on
+ instances declared in a section so that their generalization is automatically
+ redeclared after the section is closed.
+
+\item {\tt Program Instance} \comindex{Program Instance}
+ Switches the type-checking to \Program~(chapter \ref{Program})
+ and uses the obligation mechanism to manage missing fields.
+
+\item {\tt Declare Instance} \comindex{Declare Instance}
+ In a {\tt Module Type}, this command states that a corresponding
+ concrete instance should exist in any implementation of this
+ {\tt Module Type}. This is similar to the distinction between
+ {\tt Parameter} vs. {\tt Definition}, or between {\tt Declare Module}
+ and {\tt Module}.
+
+\end{Variants}
+
+Besides the {\tt Class} and {\tt Instance} vernacular commands, there
+are a few other commands related to type classes.
+
+\subsection{\tt Existing Instance {\ident} [| \textit{priority}]}
+\comindex{Existing Instance}
+\label{ExistingInstance}
+
+This commands adds an arbitrary constant whose type ends with an applied
+type class to the instance database with an optional priority. It can be used
+for redeclaring instances at the end of sections, or declaring structure
+projections as instances. This is almost equivalent to {\tt Hint Resolve
+{\ident} : typeclass\_instances}.
+
+\begin{Variants}
+\item {\tt Existing Instances {\ident}$_1$ \ldots {\ident}$_n$
+ [| \textit{priority}]}
+ \comindex{Existing Instances}
+ With this command, several existing instances can be declared at once.
+\end{Variants}
+
+\subsection{\tt Context {\binder$_1$ \ldots \binder$_n$}}
+\comindex{Context}
+\label{Context}
+
+Declares variables according to the given binding context, which might
+use implicit generalization (see \ref{SectionContext}).
+
+\asubsection{\tt typeclasses eauto}
+\tacindex{typeclasses eauto}
+\label{typeclasseseauto}
+
+The {\tt typeclasses eauto} tactic uses a different resolution engine
+than {\tt eauto} and {\tt auto}. The main differences are the following:
+\begin{itemize}
+\item Contrary to {\tt eauto} and {\tt auto}, the resolution is done
+ entirely in the new proof engine (as of Coq v8.6), meaning that
+ backtracking is available among dependent subgoals, and shelving goals
+ is supported. {\tt typeclasses eauto} is a multi-goal tactic.
+ It analyses the dependencies between subgoals to avoid
+ backtracking on subgoals that are entirely independent.
+\item When called with no arguments, {\tt typeclasses eauto} uses the
+ {\tt typeclass\_instances} database by default (instead of {\tt
+ core}).
+ Dependent subgoals are automatically shelved, and shelved
+ goals can remain after resolution ends (following the behavior of
+ \Coq{} 8.5).
+
+ \emph{Note: } As of Coq 8.6, {\tt all:once (typeclasses eauto)}
+ faithfully mimicks what happens during typeclass resolution when it is
+ called during refinement/type-inference, except that \emph{only}
+ declared class subgoals are considered at the start of resolution
+ during type inference, while ``all'' can select non-class subgoals as
+ well. It might move to {\tt all:typeclasses eauto} in future versions
+ when the refinement engine will be able to backtrack.
+\item When called with specific databases (e.g. {\tt with}), {\tt
+ typeclasses eauto} allows shelved goals to remain at any point
+ during search and treat typeclasses goals like any other.
+\item The transparency information of databases is used consistently for
+ all hints declared in them. It is always used when calling the unifier.
+ When considering the local hypotheses, we use the transparent
+ state of the first hint database given. Using an empty database
+ (created with {\tt Create HintDb} for example) with
+ unfoldable variables and constants as the first argument of
+ typeclasses eauto hence makes resolution with the local hypotheses use
+ full conversion during unification.
+\end{itemize}
+
+\begin{Variants}
+\item \label{depth} {\tt typeclasses eauto \zeroone{\num}}
+ \emph{Warning:} The semantics for the limit {\num} is different than
+ for {\tt auto}. By default, if no limit is given the search is
+ unbounded. Contrary to {\tt auto}, introduction steps ({\tt intro})
+ are counted, which might result in larger limits being necessary
+ when searching with {\tt typeclasses eauto} than {\tt auto}.
+
+\item \label{with} {\tt typeclasses eauto with {\ident}$_1$ \ldots {\ident}$_n$}.
+ This variant runs resolution with the given hint databases. It treats
+ typeclass subgoals the same as other subgoals (no shelving of
+ non-typeclass goals in particular).
+\end{Variants}
+
+\asubsection{\tt autoapply {\term} with {\ident}}
+\tacindex{autoapply}
+
+The tactic {\tt autoapply} applies a term using the transparency
+information of the hint database {\ident}, and does \emph{no} typeclass
+resolution. This can be used in {\tt Hint Extern}'s for typeclass
+instances (in hint db {\tt typeclass\_instances}) to
+allow backtracking on the typeclass subgoals created by the lemma
+application, rather than doing type class resolution locally at the hint
+application time.
+
+\subsection{\tt Typeclasses Transparent, Opaque {\ident$_1$ \ldots \ident$_n$}}
+\comindex{Typeclasses Transparent}
+\comindex{Typeclasses Opaque}
+\label{TypeclassesTransparency}
+
+This commands defines the transparency of {\ident$_1$ \ldots \ident$_n$}
+during type class resolution. It is useful when some constants prevent some
+unifications and make resolution fail. It is also useful to declare
+constants which should never be unfolded during proof-search, like
+fixpoints or anything which does not look like an abbreviation. This can
+additionally speed up proof search as the typeclass map can be indexed
+by such rigid constants (see \ref{HintTransparency}).
+By default, all constants and local variables are considered transparent.
+One should take care not to make opaque any constant that is used to
+abbreviate a type, like {\tt relation A := A -> A -> Prop}.
+
+This is equivalent to {\tt Hint Transparent,Opaque} {\ident} {\tt: typeclass\_instances}.
+
+\subsection{\tt Set Typeclasses Axioms Are Instances}
+\optindex{Typeclasses Axioms Are Instances}
+
+This option (off by default since 8.8) automatically declares axioms
+whose type is a typeclass at declaration time as instances of that
+class.
+
+\subsection{\tt Set Typeclasses Dependency Order}
+\optindex{Typeclasses Dependency Order}
+
+This option (on by default since 8.6) respects the dependency order between
+subgoals, meaning that subgoals which are depended on by other subgoals
+come first, while the non-dependent subgoals were put before the
+dependent ones previously (Coq v8.5 and below). This can result in quite
+different performance behaviors of proof search.
+
+\subsection{\tt Set Typeclasses Filtered Unification}
+\optindex{Typeclasses Filtered Unification}
+
+This option, available since Coq 8.6 and off by default, switches the
+hint application procedure to a filter-then-unify strategy. To apply a
+hint, we first check that the goal \emph{matches} syntactically the
+inferred or specified pattern of the hint, and only then try to
+\emph{unify} the goal with the conclusion of the hint. This can
+drastically improve performance by calling unification less often,
+matching syntactic patterns being very quick. This also provides more
+control on the triggering of instances. For example, forcing a constant
+to explicitely appear in the pattern will make it never apply on a goal
+where there is a hole in that place.
+
+\subsection{\tt Set Typeclasses Limit Intros}
+\optindex{Typeclasses Limit Intros}
+
+This option (on by default) controls the ability to
+apply hints while avoiding (functional) eta-expansions in the generated
+proof term. It does so by allowing hints that conclude in a product to
+apply to a goal with a matching product directly, avoiding an
+introduction. \emph{Warning:} this can be expensive as it requires
+rebuilding hint clauses dynamically, and does not benefit from the
+invertibility status of the product introduction rule, resulting in
+potentially more expensive proof-search (i.e. more useless
+backtracking).
+
+\subsection{\tt Set Typeclass Resolution For Conversion}
+\optindex{Typeclass Resolution For Conversion}
+
+This option (on by default) controls the use of typeclass resolution
+when a unification problem cannot be solved during
+elaboration/type-inference. With this option on, when a unification
+fails, typeclass resolution is tried before launching unification once again.
+
+\subsection{\tt Set Typeclasses Strict Resolution}
+\optindex{Typeclasses Strict Resolution}
+
+Typeclass declarations introduced when this option is set have a
+stricter resolution behavior (the option is off by default). When
+looking for unifications of a goal with an instance of this class, we
+``freeze'' all the existentials appearing in the goals, meaning that
+they are considered rigid during unification and cannot be instantiated.
+
+\subsection{\tt Set Typeclasses Unique Solutions}
+\optindex{Typeclasses Unique Solutions}
+
+When a typeclass resolution is launched we ensure that it has a single
+solution or fail. This ensures that the resolution is canonical, but can
+make proof search much more expensive.
+
+\subsection{\tt Set Typeclasses Unique Instances}
+\optindex{Typeclasses Unique Instances}
+
+Typeclass declarations introduced when this option is set have a
+more efficient resolution behavior (the option is off by default). When
+a solution to the typeclass goal of this class is found, we never
+backtrack on it, assuming that it is canonical.
+
+\subsection{\tt Typeclasses eauto := [debug] [(dfs) | (bfs)] [\emph{depth}]}
+\comindex{Typeclasses eauto}
+\label{TypeclassesEauto}
+
+This command allows more global customization of the type class
+resolution tactic.
+The semantics of the options are:
+\begin{itemize}
+\item {\tt debug} In debug mode, the trace of successfully applied
+ tactics is printed.
+\item {\tt dfs, bfs} This sets the search strategy to depth-first search
+ (the default) or breadth-first search.
+\item {\emph{depth}} This sets the depth limit of the search.
+\end{itemize}
+
+\subsection{\tt Set Typeclasses Debug [Verbosity {\num}]}
+\optindex{Typeclasses Debug}
+\optindex{Typeclasses Debug Verbosity}
+
+These options allow to see the resolution steps of typeclasses that are
+performed during search. The {\tt Debug} option is synonymous to
+{\tt Debug Verbosity 1}, and {\tt Debug Verbosity 2} provides more
+information (tried tactics, shelving of goals, etc\ldots).
+
+\subsection{\tt Set Refine Instance Mode}
+\optindex{Refine Instance Mode}
+
+The option {\tt Refine Instance Mode} allows to switch the behavior of instance
+declarations made through the {\tt Instance} command.
+\begin{itemize}
+\item When it is on (the default), instances that have unsolved holes in their
+proof-term silently open the proof mode with the remaining obligations to prove.
+\item When it is off, they fail with an error instead.
+\end{itemize}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "Reference-Manual"
+%%% End: