aboutsummaryrefslogtreecommitdiffhomepage
path: root/doc/sphinx/addendum/extraction.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/sphinx/addendum/extraction.rst')
-rw-r--r--doc/sphinx/addendum/extraction.rst139
1 files changed, 69 insertions, 70 deletions
diff --git a/doc/sphinx/addendum/extraction.rst b/doc/sphinx/addendum/extraction.rst
index d7f97edab..cb93d48a4 100644
--- a/doc/sphinx/addendum/extraction.rst
+++ b/doc/sphinx/addendum/extraction.rst
@@ -1,16 +1,16 @@
-.. _extraction:
-
.. include:: ../replaces.rst
-Extraction of programs in OCaml and Haskell
-============================================
+.. _extraction:
+
+Extraction of programs in |OCaml| and Haskell
+=============================================
:Authors: Jean-Christophe FilliĆ¢tre and Pierre Letouzey
We present here the |Coq| extraction commands, used to build certified
and relatively efficient functional programs, extracting them from
either |Coq| functions or |Coq| proofs of specifications. The
-functional languages available as output are currently OCaml, Haskell
+functional languages available as output are currently |OCaml|, Haskell
and Scheme. In the following, "ML" will be used (abusively) to refer
to any of the three.
@@ -37,11 +37,11 @@ Generating ML Code
The next two commands are meant to be used for rapid preview of
extraction. They both display extracted term(s) inside |Coq|.
-.. cmd:: Extraction @qualid.
+.. cmd:: Extraction @qualid
Extraction of the mentioned object in the |Coq| toplevel.
-.. cmd:: Recursive Extraction @qualid ... @qualid.
+.. cmd:: Recursive Extraction {+ @qualid }
Recursive extraction of all the mentioned objects and
all their dependencies in the |Coq| toplevel.
@@ -49,7 +49,7 @@ extraction. They both display extracted term(s) inside |Coq|.
All the following commands produce real ML files. User can choose to
produce one monolithic file or one file per |Coq| library.
-.. cmd:: Extraction "@file" @qualid ... @qualid.
+.. cmd:: Extraction "@file" {+ @qualid }
Recursive extraction of all the mentioned objects and all
their dependencies in one monolithic `file`.
@@ -57,43 +57,43 @@ produce one monolithic file or one file per |Coq| library.
language to fulfill its syntactic conventions, keeping original
names as much as possible.
-.. cmd:: Extraction Library @ident.
+.. cmd:: Extraction Library @ident
Extraction of the whole |Coq| library ``ident.v`` to an ML module
``ident.ml``. In case of name clash, identifiers are here renamed
using prefixes ``coq_`` or ``Coq_`` to ensure a session-independent
renaming.
-.. cmd:: Recursive Extraction Library @ident.
+.. cmd:: Recursive Extraction Library @ident
Extraction of the |Coq| library ``ident.v`` and all other modules
``ident.v`` depends on.
-.. cmd:: Separate Extraction @qualid ... @qualid.
+.. cmd:: Separate Extraction {+ @qualid }
Recursive extraction of all the mentioned objects and all
their dependencies, just as ``Extraction "file"``,
but instead of producing one monolithic file, this command splits
the produced code in separate ML files, one per corresponding Coq
``.v`` file. This command is hence quite similar to
- ``Recursive Extraction Library``, except that only the needed
+ :cmd:`Recursive Extraction Library`, except that only the needed
parts of Coq libraries are extracted instead of the whole.
The naming convention in case of name clash is the same one as
- ``Extraction Library``: identifiers are here renamed using prefixes
+ :cmd:`Extraction Library`: identifiers are here renamed using prefixes
``coq_`` or ``Coq_``.
The following command is meant to help automatic testing of
the extraction, see for instance the ``test-suite`` directory
in the |Coq| sources.
-.. cmd:: Extraction TestCompile @qualid ... @qualid.
+.. cmd:: Extraction TestCompile {+ @qualid }
All the mentioned objects and all their dependencies are extracted
- to a temporary OCaml file, just as in ``Extraction "file"``. Then
+ to a temporary |OCaml| file, just as in ``Extraction "file"``. Then
this temporary file and its signature are compiled with the same
- OCaml compiler used to built |Coq|. This command succeeds only
- if the extraction and the OCaml compilation succeed. It fails
- if the current target language of the extraction is not OCaml.
+ |OCaml| compiler used to built |Coq|. This command succeeds only
+ if the extraction and the |OCaml| compilation succeed. It fails
+ if the current target language of the extraction is not |OCaml|.
Extraction Options
-------------------
@@ -102,26 +102,26 @@ Setting the target language
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ability to fix target language is the first and more important
-of the extraction options. Default is ``Ocaml``.
+of the extraction options. Default is ``OCaml``.
-.. cmd:: Extraction Language Ocaml.
-.. cmd:: Extraction Language Haskell.
-.. cmd:: Extraction Language Scheme.
+.. cmd:: Extraction Language OCaml
+.. cmd:: Extraction Language Haskell
+.. cmd:: Extraction Language Scheme
Inlining and optimizations
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Since OCaml is a strict language, the extracted code has to
+Since |OCaml| is a strict language, the extracted code has to
be optimized in order to be efficient (for instance, when using
induction principles we do not want to compute all the recursive calls
but only the needed ones). So the extraction mechanism provides an
automatic optimization routine that will be called each time the user
-want to generate OCaml programs. The optimizations can be split in two
+want to generate |OCaml| programs. The optimizations can be split in two
groups: the type-preserving ones (essentially constant inlining and
reductions) and the non type-preserving ones (some function
abstractions of dummy types are removed when it is deemed safe in order
to have more elegant types). Therefore some constants may not appear in the
-resulting monolithic OCaml program. In the case of modular extraction,
+resulting monolithic |OCaml| program. In the case of modular extraction,
even if some inlining is done, the inlined constant are nevertheless
printed, to ensure session-independent programs.
@@ -131,14 +131,14 @@ order to produce more readable code.
The type-preserving optimizations are controlled by the following |Coq| options:
-.. opt:: Extraction Optimize.
+.. opt:: Extraction Optimize
Default is on. This controls all type-preserving optimizations made on
the ML terms (mostly reduction of dummy beta/iota redexes, but also
simplifications on Cases, etc). Turn this option off if you want a
ML term as close as possible to the Coq term.
-.. opt:: Extraction Conservative Types.
+.. opt:: Extraction Conservative Types
Default is off. This controls the non type-preserving optimizations
made on ML terms (which try to avoid function abstraction of dummy
@@ -146,7 +146,7 @@ The type-preserving optimizations are controlled by the following |Coq| options:
implies that ``e':t'`` where ``e'`` and ``t'`` are the extracted
code of ``e`` and ``t`` respectively.
-.. opt:: Extraction KeepSingleton.
+.. opt:: Extraction KeepSingleton
Default is off. Normally, when the extraction of an inductive type
produces a singleton type (i.e. a type with only one constructor, and
@@ -155,7 +155,7 @@ The type-preserving optimizations are controlled by the following |Coq| options:
The typical example is ``sig``. This option allows disabling this
optimization when one wishes to preserve the inductive structure of types.
-.. opt:: Extraction AutoInline.
+.. opt:: Extraction AutoInline
Default is on. The extraction mechanism inlines the bodies of
some defined constants, according to some heuristics
@@ -163,22 +163,22 @@ The type-preserving optimizations are controlled by the following |Coq| options:
Those heuristics are not always perfect; if you want to disable
this feature, turn this option off.
-.. cmd:: Extraction Inline @qualid ... @qualid.
+.. cmd:: Extraction Inline {+ @qualid }
In addition to the automatic inline feature, the constants
mentionned by this command will always be inlined during extraction.
-.. cmd:: Extraction NoInline @qualid ... @qualid.
+.. cmd:: Extraction NoInline {+ @qualid }
Conversely, the constants mentionned by this command will
never be inlined during extraction.
-.. cmd:: Print Extraction Inline.
+.. cmd:: Print Extraction Inline
Prints the current state of the table recording the custom inlinings
declared by the two previous commands.
-.. cmd:: Reset Extraction Inline.
+.. cmd:: Reset Extraction Inline
Empties the table recording the custom inlinings (see the
previous commands).
@@ -213,7 +213,7 @@ code elimination performed during extraction, in a way which
is independent but complementary to the main elimination
principles of extraction (logical parts and types).
-.. cmd:: Extraction Implicit @qualid [ @ident ... @ident ].
+.. cmd:: Extraction Implicit @qualid [ {+ @ident } ]
This experimental command allows declaring some arguments of
`qualid` as implicit, i.e. useless in extracted code and hence to
@@ -223,11 +223,11 @@ principles of extraction (logical parts and types).
by a number indicating its position, starting from 1.
When an actual extraction takes place, an error is normally raised if the
-``Extraction Implicit`` declarations cannot be honored, that is
+:cmd:`Extraction Implicit` declarations cannot be honored, that is
if any of the implicited variables still occurs in the final code.
This behavior can be relaxed via the following option:
-.. opt:: Extraction SafeImplicits.
+.. opt:: Extraction SafeImplicits
Default is on. When this option is off, a warning is emitted
instead of an error if some implicited variables still occur in the
@@ -253,21 +253,20 @@ a closed term, and of course the system cannot guess the program which
realizes an axiom. Therefore, it is possible to tell the system
what ML term corresponds to a given axiom.
-.. cmd:: Extract Constant @qualid => @string.
+.. cmd:: Extract Constant @qualid => @string
Give an ML extraction for the given constant.
The `string` may be an identifier or a quoted string.
-.. cmd:: Extract Inlined Constant @qualid => @string.
+.. cmd:: Extract Inlined Constant @qualid => @string
Same as the previous one, except that the given ML terms will
be inlined everywhere instead of being declared via a ``let``.
.. note::
-
- This command is sugar for an ``Extract Constant`` followed
- by a ``Extraction Inline``. Hence a ``Reset Extraction Inline``
- will have an effect on the realized and inlined axiom.
+ This command is sugar for an :cmd:`Extract Constant` followed
+ by a :cmd:`Extraction Inline`. Hence a :cmd:`Reset Extraction Inline`
+ will have an effect on the realized and inlined axiom.
.. caution:: It is the responsibility of the user to ensure that the ML
terms given to realize the axioms do have the expected types. In
@@ -286,7 +285,7 @@ Notice that in the case of type scheme axiom (i.e. whose type is an
arity, that is a sequence of product finished by a sort), then some type
variables have to be given (as quoted strings). The syntax is then:
-.. cmdv:: Extract Constant @qualid @string ... @string => @string.
+.. cmdv:: Extract Constant @qualid @string ... @string => @string
The number of type variables is checked by the system. For example:
@@ -295,7 +294,7 @@ The number of type variables is checked by the system. For example:
Axiom Y : Set -> Set -> Set.
Extract Constant Y "'a" "'b" => " 'a * 'b ".
-Realizing an axiom via ``Extract Constant`` is only useful in the
+Realizing an axiom via :cmd:`Extract Constant` is only useful in the
case of an informative axiom (of sort ``Type`` or ``Set``). A logical axiom
have no computational content and hence will not appears in extracted
terms. But a warning is nonetheless issued if extraction encounters a
@@ -315,7 +314,7 @@ The system also provides a mechanism to specify ML terms for inductive
types and constructors. For instance, the user may want to use the ML
native boolean type instead of |Coq| one. The syntax is the following:
-.. cmd:: Extract Inductive @qualid => @string [ @string ... @string ].
+.. cmd:: Extract Inductive @qualid => @string [ {+ @string } ]
Give an ML extraction for the given inductive type. You must specify
extractions for the type itself (first `string`) and all its
@@ -323,7 +322,7 @@ native boolean type instead of |Coq| one. The syntax is the following:
the ML extraction must be an ML inductive datatype, and the native
pattern-matching of the language will be used.
-.. cmdv:: Extract Inductive @qualid => @string [ @string ... @string ] @string.
+.. cmdv:: Extract Inductive @qualid => @string [ {+ @string } ] @string
Same as before, with a final extra `string` that indicates how to
perform pattern-matching over this inductive type. In this form,
@@ -336,10 +335,10 @@ native boolean type instead of |Coq| one. The syntax is the following:
argument is considered to have one unit argument, in order to block
early evaluation of the branch: ``| O => bar`` leads to the functional
form ``(fun () -> bar)``. For instance, when extracting ``nat``
- into OCaml ``int``, the code to provide has type:
+ into |OCaml| ``int``, the code to provide has type:
``(unit->'a)->(int->'a)->int->'a``.
-.. caution:: As for ``Extract Constant``, this command should be used with care:
+.. caution:: As for :cmd:`Extract Constant`, this command should be used with care:
* The ML code provided by the user is currently **not** checked at all by
extraction, even for syntax errors.
@@ -347,17 +346,17 @@ native boolean type instead of |Coq| one. The syntax is the following:
* Extracting an inductive type to a pre-existing ML inductive type
is quite sound. But extracting to a general type (by providing an
ad-hoc pattern-matching) will often **not** be fully rigorously
- correct. For instance, when extracting ``nat`` to OCaml ``int``,
+ correct. For instance, when extracting ``nat`` to |OCaml| ``int``,
it is theoretically possible to build ``nat`` values that are
- larger than OCaml ``max_int``. It is the user's responsibility to
+ larger than |OCaml| ``max_int``. It is the user's responsibility to
be sure that no overflow or other bad events occur in practice.
* Translating an inductive type to an arbitrary ML type does **not**
magically improve the asymptotic complexity of functions, even if the
ML type is an efficient representation. For instance, when extracting
- ``nat`` to OCaml ``int``, the function ``Nat.mul`` stays quadratic.
+ ``nat`` to |OCaml| ``int``, the function ``Nat.mul`` stays quadratic.
It might be interesting to associate this translation with
- some specific ``Extract Constant`` when primitive counterparts exist.
+ some specific :cmd:`Extract Constant` when primitive counterparts exist.
Typical examples are the following:
@@ -369,9 +368,9 @@ Typical examples are the following:
.. note::
- When extracting to Ocaml, if an inductive constructor or type has arity 2 and
+ When extracting to |OCaml|, if an inductive constructor or type has arity 2 and
the corresponding string is enclosed by parentheses, and the string meets
- Ocaml's lexical criteria for an infix symbol, then the rest of the string is
+ |OCaml|'s lexical criteria for an infix symbol, then the rest of the string is
used as infix constructor or type.
.. coqtop:: in
@@ -380,7 +379,7 @@ Typical examples are the following:
Extract Inductive prod => "(*)" [ "(,)" ].
As an example of translation to a non-inductive datatype, let's turn
-``nat`` into OCaml ``int`` (see caveat above):
+``nat`` into |OCaml| ``int`` (see caveat above):
.. coqtop:: in
@@ -389,28 +388,28 @@ As an example of translation to a non-inductive datatype, let's turn
Avoiding conflicts with existing filenames
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When using ``Extraction Library``, the names of the extracted files
+When using :cmd:`Extraction Library`, the names of the extracted files
directly depends from the names of the |Coq| files. It may happen that
these filenames are in conflict with already existing files,
either in the standard library of the target language or in other
code that is meant to be linked with the extracted code.
-For instance the module ``List`` exists both in |Coq| and in OCaml.
+For instance the module ``List`` exists both in |Coq| and in |OCaml|.
It is possible to instruct the extraction not to use particular filenames.
-.. cmd:: Extraction Blacklist @ident ... @ident.
+.. cmd:: Extraction Blacklist {+ @ident }
Instruct the extraction to avoid using these names as filenames
for extracted code.
-.. cmd:: Print Extraction Blacklist.
+.. cmd:: Print Extraction Blacklist
Show the current list of filenames the extraction should avoid.
-.. cmd:: Reset Extraction Blacklist.
+.. cmd:: Reset Extraction Blacklist
Allow the extraction to use any filename.
-For OCaml, a typical use of these commands is
+For |OCaml|, a typical use of these commands is
``Extraction Blacklist String List``.
Differences between |Coq| and ML type systems
@@ -418,7 +417,7 @@ Differences between |Coq| and ML type systems
Due to differences between |Coq| and ML type systems,
some extracted programs are not directly typable in ML.
-We now solve this problem (at least in OCaml) by adding
+We now solve this problem (at least in |OCaml|) by adding
when needed some unsafe casting ``Obj.magic``, which give
a generic type ``'a`` to any term.
@@ -432,7 +431,7 @@ function:
Definition dp {A B:Type}(x:A)(y:B)(f:forall C:Type, C->C) := (f A x, f B y).
-In Ocaml, for instance, the direct extracted term would be::
+In |OCaml|, for instance, the direct extracted term would be::
let dp x y f = Pair((f () x),(f () y))
@@ -455,12 +454,12 @@ of a constructor; for example:
Inductive anything : Type := dummy : forall A:Set, A -> anything.
which corresponds to the definition of an ML dynamic type.
-In OCaml, we must cast any argument of the constructor dummy
+In |OCaml|, we must cast any argument of the constructor dummy
(no GADT are produced yet by the extraction).
Even with those unsafe castings, you should never get error like
``segmentation fault``. In fact even if your program may seem
-ill-typed to the Ocaml type-checker, it can't go wrong : it comes
+ill-typed to the |OCaml| type-checker, it can't go wrong : it comes
from a Coq well-typed terms, so for example inductive types will always
have the correct number of arguments, etc. Of course, when launching
manually some extracted function, you should apply it to arguments
@@ -470,14 +469,14 @@ More details about the correctness of the extracted programs can be
found in :cite:`Let02`.
We have to say, though, that in most "realistic" programs, these problems do not
-occur. For example all the programs of Coq library are accepted by the OCaml
+occur. For example all the programs of Coq library are accepted by the |OCaml|
type-checker without any ``Obj.magic`` (see examples below).
Some examples
-------------
We present here two examples of extractions, taken from the
-|Coq| Standard Library. We choose OCaml as target language,
+|Coq| Standard Library. We choose |OCaml| as target language,
but all can be done in the other dialects with slight modifications.
We then indicate where to find other examples and tests of extraction.
@@ -493,7 +492,7 @@ This module contains a theorem ``eucl_dev``, whose type is::
where ``diveucl`` is a type for the pair of the quotient and the
modulo, plus some logical assertions that disappear during extraction.
-We can now extract this program to OCaml:
+We can now extract this program to |OCaml|:
.. coqtop:: none
@@ -513,7 +512,7 @@ You can then copy-paste the output to a file ``euclid.ml`` or let
Extraction "euclid" eucl_dev.
-Let us play the resulting program (in an OCaml toplevel)::
+Let us play the resulting program (in an |OCaml| toplevel)::
#use "euclid.ml";;
type nat = O | S of nat
@@ -527,7 +526,7 @@ Let us play the resulting program (in an OCaml toplevel)::
# eucl_dev (S (S O)) (S (S (S (S (S O)))));;
- : diveucl = Divex (S (S O), S O)
-It is easier to test on OCaml integers::
+It is easier to test on |OCaml| integers::
# let rec nat_of_int = function 0 -> O | n -> S (nat_of_int (n-1));;
val nat_of_int : int -> nat = <fun>