summaryrefslogtreecommitdiffstats
path: root/site/posts/CoqffiIntro.org
diff options
context:
space:
mode:
Diffstat (limited to 'site/posts/CoqffiIntro.org')
-rw-r--r--site/posts/CoqffiIntro.org516
1 files changed, 0 insertions, 516 deletions
diff --git a/site/posts/CoqffiIntro.org b/site/posts/CoqffiIntro.org
deleted file mode 100644
index e85f4b4..0000000
--- a/site/posts/CoqffiIntro.org
+++ /dev/null
@@ -1,516 +0,0 @@
-#+TITLE: ~coqffi~ in a Nutshell
-
-#+SERIES: ./Coqffi.html
-#+SERIES_NEXT: ./CoqffiEcho.html
-
-For each entry of a ~cmi~ file (a /compiled/ ~mli~ file), ~coqffi~
-tries to generate an equivalent (from the extraction mechanism
-perspective) Coq definition. In this article, we walk through how
-~coqffi~ works.
-
-Note that we do not dive into the vernacular commands ~coqffi~
-generates. They are of no concern for users of ~coqffi~.
-
-#+BEGIN_EXPORT html
-<nav id="generate-toc"></nav>
-<div id="history">site/posts/CoqffiIntro.org</div>
-#+END_EXPORT
-
-* Getting Started
-
-** Requirements
-
-The latest version of ~coqffi~ (~1.0.0~beta7~ at the time of writing)
-is compatible with OCaml ~4.08~ up to ~4.12~, and Coq ~8.12~ up top
-~8.13~. If you want to use ~coqffi~, but have incompatible
-requirements of your own, feel free to
-[[https://github.com/coq-community/coqffi/issues][submit an issue]].
-
-** Installing ~coqffi~
-
-The recommended way to install ~coqffi~ is through the
-[[https://coq.inria.fr/opam/www][Opam Coq Archive]], in the ~released~
-repository. If you haven’t activated this repository yet, you can use
-the following bash command.
-
-#+BEGIN_SRC sh
-opam repo add coq-released https://coq.inria.fr/opam/released
-#+END_SRC
-
-Then, installing ~coqffi~ is as simple as
-
-#+BEGIN_SRC sh
-opam install coq-coqffi
-#+END_SRC
-
-You can also get the source from
-[[https://github.com/coq-community/coqffi][the upstream ~git~
-repository]]. The ~README~ provides the necessary pieces of
-information to build it from source.
-
-** Additional Dependencies
-
-One major difference between Coq and OCaml is that the former is pure,
-while the latter is not. Impurity can be modeled in pure languages,
-and Coq does not lack of frameworks in this respect. ~coqffi~
-currently supports two of them: [[https://github.com/Lysxia/coq-simple-io][~coq-simple-io~]] and [[https://github.com/ANSSI-FR/FreeSpec][FreeSpec]]. It is
-also possible to use it with [[https://github.com/DeepSpec/InteractionTrees][Interaction Trees]], albeit in a less
-direct manner.
-
-* Primitive Types
-
-~coqffi~ supports a set of primitive types, /i.e./, a set of OCaml
-types for which it knows an equivalent type in Coq. The list is the
-following (the Coq types are fully qualified in the table, but not in
-the generated Coq module as the necessary ~Import~ statement are
-generated too).
-
-| OCaml type | Coq type |
-|-------------------+-------------------------------|
-| =bool= | =Coq.Init.Datatypes.bool= |
-| =char= | =Coq.Strings.Ascii.ascii= |
-| =int= | =CoqFFI.Data.Int.i63= |
-| ='a list= | =Coq.Init.Datatypes.list a= |
-| ='a Seq.t= | =CoqFFI.Data.Seq.t= |
-| ='a option= | =Coq.Init.Datatypes.option a= |
-| =('a, 'e) result= | =Coq.Init.Datatypes.sum= |
-| =string= | =Coq.Strings.String.string= |
-| =unit= | =Coq.Init.Datatypes.unit= |
-| =exn= | =CoqFFI.Exn= |
-
-The =i63= type is introduced by the =CoqFFI= theory to provide signed
-primitive integers to Coq users. They are implemented on top of the
-(sadly unsigned) Coq native integers introduced in Coq
-~8.10~. Hopefully, the =i63= type will be deprecated once [[https://github.com/coq/coq/pull/13559][signed
-primitive integers find their way to Coq upstream]].
-
-When processing the entries of a given interface model, ~coqffi~ will
-check that they only use these types, or types introduced by the
-interface module itself.
-
-Sometimes, you may encounter a situation where you have two interface
-modules ~b.mli~ and ~b.mli~, such that ~b.mli~ uses a type introduced
-in ~a.mli~. To deal with this scenario, you can use the ~--witness~
-flag to generate ~A.v~. This will tell ~coqffi~ to also generate
-~A.ffi~; this file can then be used when generating ~B.v~ thanks to
-the ~-I~ option. Furthermore, for ~B.v~ to compile the ~--require~
-option needs to be used to ensure the ~A~ Coq library (~A.v~) is
-required.
-
-To give a more concrete example, given ~a.mli~
-
-#+BEGIN_SRC ocaml
-type t
-#+END_SRC
-
-and ~b.mli~
-
-#+BEGIN_SRC ocaml
-type a = A.t
-#+END_SRC
-
-To generate ~A.v~, we can use the following commands:
-
-#+BEGIN_SRC bash
-ocamlc a.mli
-coqffi --witness -o A.v a.cmi
-#+END_SRC
-
-Which would generate the following axiom for =t=.
-
-#+BEGIN_SRC coq
-Axiom t : Type.
-#+END_SRC
-
-Then, generating ~B.v~ can be achieved as follows:
-
-#+BEGIN_SRC bash
-ocamlc b.mli
-coqffi -I A.ffi -ftransparent-types -r A -o B.v b.cmi
-#+END_SRC
-
-which results in the following output for =v=:
-
-#+BEGIN_SRC coq
-Require A.
-
-Definition u : Type := A.t.
-#+END_SRC
-
-* Code Generation
-
-~coqffi~ distinguishes five types of entries: types, pure values,
-impure primitives, asynchronous primitives, exceptions, and
-modules. We now discuss how each one of them is handled.
-
-** Types
-
-By default, ~coqffi~ generates axiomatized definitions for each type
-defined in a ~.cmi~ file. This means that src_ocaml[:exports
-code]{type t} becomes src_coq[:exports code]{Axiom t : Type}.
-Polymorphism is supported, /i.e./, src_ocaml[:exports code]{type 'a t}
-becomes src_coq[:exports code]{Axiom t : forall (a : Type), Type}.
-
-It is possible to provide a “model” for a type using the =coq_model=
-annotation, for instance for reasoning purposes. For instance,
-we can specify that a type is equivalent to a =list=.
-
-#+BEGIN_SRC ocaml
-type 'a t [@@coq_model "list"]
-#+END_SRC
-
-This generates the following Coq definition.
-
-#+BEGIN_SRC coq
-Definition t : forall (a : Type), Type := list.
-#+END_SRC
-
-It is important to be careful when using the =coq_model= annotation.
-More precisely, the fact that =t= is a =list= in the “Coq universe”
-shall not be used while the implementation phase, only the
-verification phase.
-
-Unamed polymorphic type parameters are also supported. In presence of
-such parameters, ~coqffi~ will find it a name that is not already
-used. For instance,
-
-#+BEGIN_SRC ocaml
-type (_, 'a) ast
-#+END_SRC
-
-becomes
-
-#+BEGIN_SRC ocaml
-Axiom ast : forall (b : Type) (a : Type), Type.
-#+END_SRC
-
-Finally, ~coqffi~ has got an experimental feature called
-~transparent-types~ (enabled by using the ~-ftransparent-types~
-command-line argument). If the type definition is given in the module
-interface, then ~coqffi~ tries to generates an equivalent definition
-in Coq. For instance,
-
-#+BEGIN_SRC ocaml
-type 'a llist =
- | LCons of 'a * (unit -> 'a llist)
- | LNil
-#+END_SRC
-
-becomes
-
-#+BEGIN_SRC coq
-Inductive llist (a : Type) : Type :=
-| LCons (x0 : a) (x1 : unit -> llist a) : llist a
-| LNil : llist a.
-#+END_SRC
-
-Mutually recursive types are supported, so
-
-#+BEGIN_SRC ocaml
-type even = Zero | ESucc of odd
-and odd = OSucc of even
-#+END_SRC
-
-becomes
-
-#+BEGIN_SRC coq
-Inductive odd : Type :=
-| OSucc (x0 : even) : odd
-with even : Type :=
-| Zero : even
-| ESucc (x0 : odd) : even.
-#+END_SRC
-
-Besides, ~coqffi~ supports alias types, as suggested in this write-up
-when we discuss witness files.
-
-The ~transparent-types~ feature is *experimental*, and is currently
-limited to variant types. It notably does not support
-records. Besides, it may generate incorrect Coq types, because it does
-not check whether or not the [[https://coq.inria.fr/refman/language/core/inductive.html#positivity-condition][positivity condition]] is
-satisfied.
-
-** Pure values
-
-~coqffi~ decides whether or not a given OCaml values is pure or impure
-with the following heuristics:
-
-- Constants are pure
-- Functions are impure by default
-- Functions with a =coq_model= annotation are pure
-- Functions marked with the =pure= annotation are pure
-- If the ~pure-module~ feature is enabled (~-fpure-module~),
- then synchronous functions (which do not live inside the [[https://ocsigen.org/lwt/5.3.0/manual/manual][~Lwt~]]
- monad) are pure
-
-Similarly to types, ~coqffi~ generates axioms (or definitions, if the
-~coq_model~ annotation is used) for pure values. Then,
-
-#+BEGIN_SRC ocaml
-val unpack : string -> (char * string) option [@@pure]
-#+END_SRC
-
-becomes
-
-#+BEGIN_SRC coq
-Axiom unpack : string -> option (ascii * string).
-#+END_SRC
-
-Polymorphic values are supported.
-
-#+BEGIN_SRC ocaml
-val map : ('a -> 'b) -> 'a list -> 'b list [@@pure]
-#+END_SRC
-
-becomes
-
-#+BEGIN_SRC coq
-Axiom map : forall (a : Type) (b : Type), (a -> b) -> list a -> list b.
-#+END_SRC
-
-Again, unamed polymorphic type are supported, so
-
-#+BEGIN_SRC ocaml
-val ast_to_string : _ ast -> string [@@pure]
-#+END_SRC
-
-becomes
-
-#+BEGIN_SRC coq
-Axiom ast_to_string : forall (a : Type), string.
-#+END_SRC
-
-** Impure Primitives
-
-~coqffi~ reserves a special treatment for /impure/ OCaml functions.
-Impurity is usually handled in pure programming languages by means of
-monads, and ~coqffi~ is no exception to the rule.
-
-Given the set of impure primitives declared in an interface module,
-~coqffi~ will (1) generate a typeclass which gathers these primitives,
-and (2) generate instances of this typeclass for supported backends.
-
-We illustrate the rest of this section with the following impure
-primitives.
-
-#+BEGIN_SRC ocaml
-val echo : string -> unit
-val scan : unit -> string
-#+END_SRC
-
-where =echo= allows writing something the standard output, and =scan=
-to read the standard input.
-
-Assuming the processed module interface is named ~console.mli~, the
-following Coq typeclass is generated.
-
-#+BEGIN_SRC coq
-Class MonadConsole (m : Type -> Type) := { echo : string -> m unit
- ; scan : unit -> m string
- }.
-#+END_SRC
-
-Using this typeclass and with the additional support of an additional
-=Monad= typeclass, we can specify impure computations which interacts
-with the console. For instance, with the support of ~ExtLib~, one can
-write.
-
-#+BEGIN_SRC coq
-Definition pipe `{Monad m, MonadConsole m} : m unit :=
- let* msg := scan () in
- echo msg.
-#+END_SRC
-
-There is no canonical way to model impurity in Coq, but over the years
-several frameworks have been released to tackle this challenge.
-
-~coqffi~ provides three features related to impure primitives.
-
-*** ~simple-io~
-
-When this feature is enabled, ~coqffi~ generates an instance of the
-typeclass for the =IO= monad introduced in the ~coq-simple-io~ package
-
-#+BEGIN_SRC coq
-Axiom io_echo : string -> IO unit.
-Axiom io_scan : unit -> IO string.
-
-Instance IO_MonadConsole : MonadConsole IO := { echo := io_echo
- ; scan := io_scan
- }.
-#+END_SRC
-
-It is enabled by default, but can be disabled using the
-~-fno-simple-io~ command-line argument.
-
-*** ~interface~
-
-When this feature is enabled, ~coqffi~ generates an inductive type
-which describes the set of primitives available, to be used with
-frameworks like [[https://github.com/ANSSI-FR/FreeSpec][FreeSpec]] or
-[[https://github.com/DeepSpec/InteractionTrees][Interactions Trees]]
-
-#+BEGIN_SRC coq
-Inductive CONSOLE : Type -> Type :=
-| Echo : string -> CONSOLE unit
-| Scan : unit -> CONSOLE string.
-
-Definition inj_echo `{Inject CONSOLE m} (x0 : string) : m unit :=
- inject (Echo x0).
-
-Definition inj_scan `{Inject CONSOLE m} (x0 : unit) : m string :=
- inject (Scan x0).
-
-Instance Inject_MonadConsole `{Inject CONSOLE m} : MonadConsole m :=
- { echo := inj_echo
- ; scan := inj_scan
- }.
-#+END_SRC
-
-Providing an instance of the form src_coq[:exports code]{forall i,
-Inject i M} is enough for your monad =M= to be compatible with this
-feature (see for instance
-[[https://github.com/ANSSI-FR/FreeSpec/blob/master/theories/FFI/FFI.v][how
-FreeSpec implements it]]).
-
-*** ~freespec~
-
-When this feature in enabled, ~coqffi~ generates a semantics for the
-inductive type generated by the ~interface~ feature.
-
-#+BEGIN_SRC coq
-Axiom unsafe_echo : string -> unit.
-Axiom unsafe_scan : uint -> string.
-
-Definition console_unsafe_semantics : semantics CONSOLE :=
- bootstrap (fun a e =>
- local match e in CONSOLE a return a with
- | Echo x0 => unsafe_echo x0
- | Scan x0 => unsafe_scan x0
- end).
-#+END_SRC
-
-** Asynchronous Primitives
-
-~coqffi~ also reserves a special treatment for /asynchronous/
-primitives —/i.e./, functions which live inside the ~Lwt~ monad— when
-the ~lwt~ feature is enabled.
-
-The treatment is very analoguous to the one for impure primitives: (1)
-a typeclass is generated (with the ~_Async~ suffix), and (2) an
-instance for the ~Lwt~ monad is generated. Besides, an instance for
-the “synchronous” primitives is also generated for ~Lwt~. If the
-~interface~ feature is enabled, an interface datatype is generated,
-which means you can potentially use Coq to reason about your
-asynchronous programs (using FreeSpec and alike, although the
-interleaving of asynchronous programs in not yet supported in
-FreeSpec).
-
-By default, the type of the ~Lwt~ monad is ~Lwt.t~. You can override
-this setting using the ~--lwt-alias~ option. This can be useful when
-you are using an alias type in place of ~Lwt.t~.
-
-** Exceptions
-
-OCaml features an exception mechanism. Developers can define their
-own exceptions using the ~exception~ keyword, whose syntax is similar
-to constructors definition. For instance,
-
-#+BEGIN_SRC ocaml
-exception Foo of int * bool
-#+END_SRC
-
-introduces a new exception =Foo= which takes two parameters of type
-=int= and =bool=. =Foo (x, y)= constructs of value of type =exn=.
-
-For each new exceptions introduced in an OCaml module, ~coqffi~
-generates (1) a so-called “proxy type,” and (2) conversion functions
-to and from this type.
-
-Coming back to our example, the “proxy type” generates by ~coqffi~ is
-
-#+BEGIN_SRC coq
-Inductive FooExn : Type :=
-| MakeFooExn (x0 : i63) (x1 : bool) : FooExn.
-#+END_SRC
-
-Then, ~coqffi~ generates conversion functions.
-
-#+BEGIN_SRC coq
-Axiom exn_of_foo : FooExn -> exn.
-Axiom foo_of_exn : exn -> option FooExn.
-#+END_SRC
-
-Besides, ~coqffi~ also generates an instance for the =Exn= typeclass
-provided by the =CoqFFI= theory:
-
-#+BEGIN_SRC coq
-Instance FooExn_Exn : Exn FooExn :=
- { to_exn := exn_of_foo
- ; of_exn := foo_of_exn
- }.
-#+END_SRC
-
-Under the hood, =exn= is an [[https://caml.inria.fr/pub/docs/manual-ocaml/extensiblevariants.html][extensible datatype]], and how ~coqffi~
-supports it will probably be generalized in future releases.
-
-Finally, ~coqffi~ has a minimal support for functions which may raise
-exceptions. Since OCaml type system does not allow to identify such
-functions, they need to be annotated explicitely, using the
-=may_raise= annotation. In such a case, ~coqffi~ will change the
-return type of the function to use the =sum= Coq inductive type.
-
-For instance,
-
-#+BEGIN_SRC ocaml
-val from_option : 'a option -> 'a [@@may_raise] [@@pure]
-#+END_SRC
-
-becomes
-
-#+BEGIN_SRC coq
-Axiom from_option : forall (a : Type), option a -> sum a exn.
-#+END_SRC
-
-** Modules
-
-Lastly, ~coqffi~ supports OCaml modules described within ~mli~ files,
-when they are specify as ~module T : sig ... end~. For instance,
-
-#+BEGIN_SRC ocaml
-module T : sig
- type t
-
- val to_string : t -> string [@@pure]
-end
-#+END_SRC
-
-becomes
-
-#+BEGIN_SRC coq
-Module T.
- Axiom t : Type.
-
- Axiom to_string : t -> string.
-End T.
-#+END_SRC
-
-As of now, the following construction is unfortunately *not*
-supported, and will be ignored by ~coqffi~:
-
-#+BEGIN_SRC coq
-module S = sig
- type t
-
- val to_string : t -> string [@@pure]
-end
-
-module T : S
-#+END_SRC
-
-* Moving Forward
-
-~coqffi~ comes with a comprehensive man page. In addition, the
-interested reader can proceed to the next article of this series,
-which explains how [[./CoqffiEcho.org][~coqffi~ can be used to easily implement an echo
-server in Coq]].