<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Thomas Letan's Blog - coq</title>
    <link>https://soap.coffee/~lthms/tags/coq.html</link>
    <description>Posts tagged "coq"</description>
    <atom:link href="https://soap.coffee/~lthms/tags/coq.xml" rel="self"
               type="application/rss+xml" />
    
    
    <item>
      <title>Implementing an Echo Server in Coq with coqffi.1.0.0</title>
      <link>https://soap.coffee/~lthms/posts/CoqffiEcho.html</link>
      <guid>https://soap.coffee/~lthms/posts/CoqffiEcho.html</guid>
      <pubDate>December 10, 2020</pubDate>
      <description>
        
        &lt;h1&gt;Implementing an Echo Server in Coq with &lt;code class=&quot;hljs&quot;&gt;coqffi.1.0.0&lt;/code&gt;&lt;/h1&gt;&lt;div id=&quot;tags-list&quot;&gt;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coq.html&quot; class=&quot;tag hover-coral&quot; marked=&quot;&quot;&gt;coq&lt;/a&gt; &lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/ocaml.html&quot; class=&quot;tag hover-peach&quot; marked=&quot;&quot;&gt;ocaml&lt;/a&gt; &lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coqffi.html&quot; class=&quot;tag hover-lemon&quot; marked=&quot;&quot;&gt;coqffi&lt;/a&gt; &lt;/div&gt;
&lt;p&gt;In this article, we will demonstrate how &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; can be used to
implement an echo server, &lt;em&gt;i.e.&lt;/em&gt;, a TCP server which sends back any
input it receives from its clients.  In addition to &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;, you will need to
install &lt;code class=&quot;hljs&quot;&gt;coq-simple-io&lt;/code&gt;.  The latter is available in the &lt;a href=&quot;https://github.com/coq/opam-coq-archive&quot; class=&quot;hover-sky&quot; marked=&quot;&quot;&gt;&lt;code class=&quot;hljs&quot;&gt;released&lt;/code&gt; repository
of the Opam Coq Archive&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot;&gt;opam install coq-coqffi coq-simple-io
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides,  you can download &lt;a href=&quot;/~lthms/files/coqffi-tutorial.tar.gz&quot; class=&quot;hover-mint&quot; marked=&quot;&quot;&gt;the source tree presented in this
article&lt;/a&gt; if you want to try to read the source
directly, or modify it to your taste.&lt;/p&gt;
&lt;h2&gt;Project Layout&lt;/h2&gt;
&lt;p&gt;Before diving too much into the implementation of our echo server, we
first give an overview of the resulting project’s layout. Since we aim
at implementing a program, we draw our inspiration from the idiomatic
way of organizing a OCaml project.&lt;/p&gt;
&lt;p&gt;We have three directories at the root of the project.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code class=&quot;hljs&quot;&gt;ffi/&lt;/code&gt; contains the low-level OCaml code:&lt;/strong&gt;
It provides an OCaml library (&lt;code class=&quot;hljs&quot;&gt;ffi&lt;/code&gt;), and a Coq theory (&lt;code class=&quot;hljs language-coq&quot;&gt;FFI&lt;/code&gt;) which
gathers the FFI modules generated by &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code class=&quot;hljs&quot;&gt;src/&lt;/code&gt; contains the Coq implementation of our echo server:&lt;/strong&gt; It provides a
Coq theory (&lt;code class=&quot;hljs language-coq&quot;&gt;Echo&lt;/code&gt;) which depends on the &lt;code class=&quot;hljs language-coq&quot;&gt;FFI&lt;/code&gt; theory the
&lt;code class=&quot;hljs language-coq&quot;&gt;SimpleIO&lt;/code&gt; theory of &lt;code class=&quot;hljs&quot;&gt;coq-simple~io&lt;/code&gt;. This theory provides the
implementation of our echo server in Coq.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code class=&quot;hljs&quot;&gt;bin/&lt;/code&gt; contains the pieces of code to get an executable program:&lt;/strong&gt; It
contains a Coq module (&lt;code class=&quot;hljs&quot;&gt;echo.v&lt;/code&gt;) which configures and uses the extraction
mechanism to generate an OCaml module (&lt;code class=&quot;hljs&quot;&gt;echo.ml&lt;/code&gt;). This OCaml module can be
compiled to get an executable program.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that we could have decided to only have one Coq theory. We could
also have added a fourth directory (&lt;code class=&quot;hljs&quot;&gt;theories/&lt;/code&gt;) for formal
verification specific code, but this is out of the scope of this
tutorial.&lt;/p&gt;
&lt;p&gt;Overall, we use &lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; to compile and compose the different parts of
the echo server. &lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; has a native —yet unstable at the time of
writing— support for building Coq projects, with very convenient
stanzas like &lt;code class=&quot;hljs&quot;&gt;coq.theory&lt;/code&gt; and &lt;code class=&quot;hljs&quot;&gt;coq.extraction&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The following graph summarizes the dependencies between each component
(plain arrows symbolize software dependencies).&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/~lthms/img/echo-deps.svg&quot; alt=&quot;The echo server dependy graph&quot;&gt;&lt;figcaption&gt;&lt;p&gt;The echo server dependency graph. Dashed boxes are generated.&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;We enable Coq-related stanza with &lt;code class=&quot;hljs language-lisp&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;using&lt;/span&gt; coq &lt;span class=&quot;hljs-number&quot;&gt;0.2&lt;/span&gt;)&lt;/code&gt; in the
&lt;code class=&quot;hljs language-dune&quot;&gt;dune-project&lt;/code&gt;. file.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-lisp&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;lang&lt;/span&gt; dune &lt;span class=&quot;hljs-number&quot;&gt;2.7&lt;/span&gt;)
(&lt;span class=&quot;hljs-name&quot;&gt;using&lt;/span&gt; coq &lt;span class=&quot;hljs-number&quot;&gt;0.2&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The rest of this tutorial proceeds by diving into each directory.&lt;/p&gt;
&lt;h2&gt;FFI Bindings&lt;/h2&gt;
&lt;p&gt;Our objective is to implement an echo server, &lt;em&gt;i.e.&lt;/em&gt;, a server which
(1) accepts incoming connections, and (2) sends back any incoming
messages. We will consider two classes of effects. One is related to
creating and manipulating TCP sockets. The other is dedicated to
process management, more precisely to be able to fork when receiving
incoming connections.&lt;/p&gt;
&lt;p&gt;Therefore, the &lt;code class=&quot;hljs&quot;&gt;ffi&lt;/code&gt; library will provide two modules. Likewise, the
&lt;code class=&quot;hljs language-coq&quot;&gt;FFI&lt;/code&gt; theory will provide two analogous modules generated by &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In the &lt;code class=&quot;hljs&quot;&gt;ffi/&lt;/code&gt; directory, we add the following stanza to the &lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-lisp&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;library&lt;/span&gt;
  (&lt;span class=&quot;hljs-name&quot;&gt;name&lt;/span&gt; ffi)
  (&lt;span class=&quot;hljs-name&quot;&gt;libraries&lt;/span&gt; unix))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; will look for any &lt;code class=&quot;hljs&quot;&gt;.ml&lt;/code&gt; and &lt;code class=&quot;hljs&quot;&gt;.mli&lt;/code&gt; files within the directory and will
consider they belong to the &lt;code class=&quot;hljs&quot;&gt;ffi&lt;/code&gt; library. We use the
&lt;a href=&quot;https://caml.inria.fr/pub/docs/manual-ocaml/libref/Unix.html&quot; class=&quot;hover-peach&quot; marked=&quot;&quot;&gt;&lt;code class=&quot;hljs&quot;&gt;unix&lt;/code&gt;&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#external-link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt; library
to implement the features we are looking for.&lt;/p&gt;
&lt;p&gt;Then, we add the following stanza to the &lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; file of the &lt;code class=&quot;hljs&quot;&gt;ffi/&lt;/code&gt;
directory.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-lisp&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;coq&lt;/span&gt;.theory
  (&lt;span class=&quot;hljs-name&quot;&gt;name&lt;/span&gt; FFI))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This tells &lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; to look for &lt;code class=&quot;hljs&quot;&gt;.v&lt;/code&gt; file within the &lt;code class=&quot;hljs&quot;&gt;ffi/&lt;/code&gt; directory,
in order to build them with Coq.  A nice feature of &lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; is that if we
automatically generate Coq files, they will be automatically “attached” to this
theory.&lt;/p&gt;
&lt;h3&gt;Sockets&lt;/h3&gt;
&lt;p&gt;Sockets are boring. The following OCaml module interface provides the
necessary type and functions to manipulate them.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; socket_descr

&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; open_socket : &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;int&lt;/span&gt; -&amp;gt; socket_descr
&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; listen : socket_descr -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;unit&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; recv : socket_descr -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; send : socket_descr -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;int&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; accept_connection : socket_descr -&amp;gt; socket_descr
&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; close_socket : socket_descr -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;unit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our focus is how to write the interface modules for &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;. Since the object
of this tutorial is not the implementation of an echo server in itself, the
implementation details of the &lt;code class=&quot;hljs&quot;&gt;ffi&lt;/code&gt; library will not be discussed, but is
provided at the end of this article.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; generates &lt;code class=&quot;hljs&quot;&gt;.cmi&lt;/code&gt; files for the &lt;code class=&quot;hljs&quot;&gt;.mli&lt;/code&gt; files of our library, and
provides the necessary bits to easily locate them. Besides, the
&lt;code class=&quot;hljs&quot;&gt;action&lt;/code&gt; stanza can be used here to tell to &lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; how to generate the
module &lt;code class=&quot;hljs&quot;&gt;Socket.v&lt;/code&gt; from &lt;code class=&quot;hljs&quot;&gt;file.cmi&lt;/code&gt;. We add the following entry to
&lt;code class=&quot;hljs&quot;&gt;ffi/dune&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-lisp&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;rule&lt;/span&gt;
  (&lt;span class=&quot;hljs-name&quot;&gt;target&lt;/span&gt; Socket.v)
  (&lt;span class=&quot;hljs-name&quot;&gt;action&lt;/span&gt; (&lt;span class=&quot;hljs-name&quot;&gt;run&lt;/span&gt; coqffi %{cmi&lt;span class=&quot;hljs-symbol&quot;&gt;:socket&lt;/span&gt;} -o %{target})))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We call &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; without any feature-related command-line argument,
which means only the &lt;code class=&quot;hljs&quot;&gt;simple-io&lt;/code&gt; feature is enabled. As a consequence,
the &lt;code class=&quot;hljs&quot;&gt;socket_descr&lt;/code&gt; type is axiomatized in Coq, and in addition to a
&lt;code class=&quot;hljs&quot;&gt;MonadSocket&lt;/code&gt; monad, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; will generate an instance for this monad
for the &lt;code class=&quot;hljs&quot;&gt;IO&lt;/code&gt; monad of &lt;code class=&quot;hljs&quot;&gt;coq-simple-io&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The stanza generates the following Coq module.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;(* This file has been generated by coqffi. *)&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Implicit&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Arguments&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Unset&lt;/span&gt; Strict &lt;span class=&quot;hljs-keyword&quot;&gt;Implicit&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Set&lt;/span&gt; Contextual &lt;span class=&quot;hljs-keyword&quot;&gt;Implicit&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Generalizable&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;All&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Variables&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Close&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Scope&lt;/span&gt; nat_scope.

&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; CoqFFI &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Export&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Extraction&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; SimpleIO &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; IO_Monad.

&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; socket_descr : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Extract&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Constant&lt;/span&gt; socket_descr =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Ffi.Socket.socket_descr&quot;&lt;/span&gt;.

&lt;span class=&quot;hljs-comment&quot;&gt;(** * Impure Primitives *)&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;(** ** Monad Definition *)&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;Class&lt;/span&gt; MonadSocket (m : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
  { open_socket : string -&amp;gt; i63 -&amp;gt; m socket_descr
  ; listen : socket_descr -&amp;gt; m unit
  ; recv : socket_descr -&amp;gt; m string
  ; send : socket_descr -&amp;gt; string -&amp;gt; m i63
  ; accept_connection : socket_descr -&amp;gt; m socket_descr
  ; close_socket : socket_descr -&amp;gt; m unit
  }.

&lt;span class=&quot;hljs-comment&quot;&gt;(** ** [IO] Instance *)&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; io_open_socket : string -&amp;gt; i63 -&amp;gt; IO socket_descr.
&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; io_listen : socket_descr -&amp;gt; IO unit.
&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; io_recv : socket_descr -&amp;gt; IO string.
&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; io_send : socket_descr -&amp;gt; string -&amp;gt; IO i63.
&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; io_accept_connection : socket_descr -&amp;gt; IO socket_descr.
&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; io_close_socket : socket_descr -&amp;gt; IO unit.

&lt;span class=&quot;hljs-keyword&quot;&gt;Extract&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Constant&lt;/span&gt; io_open_socket
  =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;(fun x1 x2 k__ -&amp;gt; k__ ((Ffi.Socket.open_socket x1 x2)))&quot;&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Extract&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Constant&lt;/span&gt; io_listen =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;(fun x1 k__ -&amp;gt; k__ ((Ffi.Socket.listen x1)))&quot;&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Extract&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Constant&lt;/span&gt; io_recv =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;(fun x1 k__ -&amp;gt; k__ ((Ffi.Socket.recv x1)))&quot;&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Extract&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Constant&lt;/span&gt; io_send
  =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;(fun x1 x2 k__ -&amp;gt; k__ ((Ffi.Socket.send x1 x2)))&quot;&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Extract&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Constant&lt;/span&gt; io_accept_connection
  =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;(fun x1 k__ -&amp;gt; k__ ((Ffi.Socket.accept_connection x1)))&quot;&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Extract&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Constant&lt;/span&gt; io_close_socket
  =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;(fun x1 k__ -&amp;gt; k__ ((Ffi.Socket.close_socket x1)))&quot;&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; IO_MonadSocket : MonadSocket IO :=
  { open_socket := io_open_socket
  ; listen := io_listen
  ; recv := io_recv
  ; send := io_send
  ; accept_connection := io_accept_connection
  ; close_socket := io_close_socket
  }.

&lt;span class=&quot;hljs-comment&quot;&gt;(* The generated file ends here. *)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Process Management&lt;/h3&gt;
&lt;p&gt;In order to avoid a client to block the server by connecting to it
without sending anything, we can fork a new process for each client.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; identity = &lt;span class=&quot;hljs-type&quot;&gt;Parent&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;int&lt;/span&gt; | &lt;span class=&quot;hljs-type&quot;&gt;Child&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; fork : &lt;span class=&quot;hljs-built_in&quot;&gt;unit&lt;/span&gt; -&amp;gt; identity
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This time, the &lt;code class=&quot;hljs&quot;&gt;proc.mli&lt;/code&gt; module interface introduces a transparent
type, /i.e./, it also provides its definition. This is a good use case
for the &lt;code class=&quot;hljs&quot;&gt;transparent-types&lt;/code&gt; feature of &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;. In the stanza for
generating &lt;code class=&quot;hljs&quot;&gt;Proc.v&lt;/code&gt;, we enable it with the &lt;code class=&quot;hljs&quot;&gt;-ftransparent-types&lt;/code&gt;
command-line argument, like this.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-lisp&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;rule&lt;/span&gt;
  (&lt;span class=&quot;hljs-name&quot;&gt;target&lt;/span&gt; Proc.v)
  (&lt;span class=&quot;hljs-name&quot;&gt;action&lt;/span&gt; (&lt;span class=&quot;hljs-name&quot;&gt;run&lt;/span&gt; coqffi -ftransparent-types %{cmi&lt;span class=&quot;hljs-symbol&quot;&gt;:proc&lt;/span&gt;} -o %{target})))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which generates the following Coq module.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;(* This file has been generated by coqffi. *)&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Implicit&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Arguments&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Unset&lt;/span&gt; Strict &lt;span class=&quot;hljs-keyword&quot;&gt;Implicit&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Set&lt;/span&gt; Contextual &lt;span class=&quot;hljs-keyword&quot;&gt;Implicit&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Generalizable&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;All&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Variables&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Close&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Scope&lt;/span&gt; nat_scope.

&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; CoqFFI &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Export&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Extraction&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; SimpleIO &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; IO_Monad.

&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; identity : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
| &lt;span class=&quot;hljs-type&quot;&gt;Parent&lt;/span&gt; (x0 : i63) : identity
| &lt;span class=&quot;hljs-type&quot;&gt;Child&lt;/span&gt; : identity.

&lt;span class=&quot;hljs-keyword&quot;&gt;Extract&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; identity =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Ffi.Proc.identity&quot;&lt;/span&gt;
  [ &lt;span class=&quot;hljs-string&quot;&gt;&quot;Ffi.Proc.Parent&quot;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Ffi.Proc.Child&quot;&lt;/span&gt; ].

&lt;span class=&quot;hljs-comment&quot;&gt;(** * Impure Primitives *)&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;(** ** Monad Definition *)&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;Class&lt;/span&gt; MonadProc (m : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; := { fork : unit -&amp;gt; m identity
                                             }.

&lt;span class=&quot;hljs-comment&quot;&gt;(** ** [IO] Instance *)&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; io_fork : unit -&amp;gt; IO identity.

&lt;span class=&quot;hljs-keyword&quot;&gt;Extract&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Constant&lt;/span&gt; io_fork =&amp;gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;(fun x1 k__ -&amp;gt; k__ ((Ffi.Proc.fork x1)))&quot;&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; IO_MonadProc : MonadProc IO := { fork := io_fork
                                        }.

&lt;span class=&quot;hljs-comment&quot;&gt;(* The generated file ends here. *)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We now have everything we need to implement an echo server in Coq.&lt;/p&gt;
&lt;h2&gt;Implementing an Echo Server&lt;/h2&gt;
&lt;p&gt;Our implementation will be part of a dedicated Coq theory, called &lt;code class=&quot;hljs language-coq&quot;&gt;Echo&lt;/code&gt;.
This is done easily a &lt;code class=&quot;hljs language-coq&quot;&gt;dune&lt;/code&gt; file in the &lt;code class=&quot;hljs&quot;&gt;src/&lt;/code&gt; directory, with the
following content.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-lisp&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;coq&lt;/span&gt;.theory
  (&lt;span class=&quot;hljs-name&quot;&gt;name&lt;/span&gt; Echo)
  (&lt;span class=&quot;hljs-name&quot;&gt;theories&lt;/span&gt; FFI))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the rest of this section, we will discuss the content of the unique
module of this theory. Hopefully, readers familiar with programming
impurity by means of monads will not find anything particularly
surprising here.&lt;/p&gt;
&lt;p&gt;Let us start with the inevitable sequence of import commands. We use
the &lt;code class=&quot;hljs language-coq&quot;&gt;Monad&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;MonadFix&lt;/code&gt; typeclasses of &lt;code class=&quot;hljs language-coq&quot;&gt;ExtLib&lt;/code&gt;, and our
FFI modules from the &lt;code class=&quot;hljs language-coq&quot;&gt;FFI&lt;/code&gt; theory we have previously defined.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; ExtLib &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Monad MonadFix.
&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; FFI &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Proc Socket.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Letting Coq guess the type of unintroduced variables using the &lt;code class=&quot;hljs&quot;&gt;`&lt;/code&gt;
annotation (&lt;em&gt;e.g.&lt;/em&gt;, in presence of&lt;code class=&quot;hljs language-coq&quot;&gt; `{Monad m}&lt;/code&gt;, Coq understands &lt;code class=&quot;hljs&quot;&gt;m&lt;/code&gt;
is of type &lt;code class=&quot;hljs&quot;&gt;Type -&amp;gt; Type&lt;/code&gt;) is always nice, so we enable it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Generalizable&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;All&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Variables&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We enable the monad notation provided by &lt;code class=&quot;hljs&quot;&gt;ExtLib&lt;/code&gt;. In this article, we
prefer the &lt;code class=&quot;hljs&quot;&gt;let*&lt;/code&gt; notation (as recently introduced by OCaml) over the
&lt;code class=&quot;hljs&quot;&gt;&amp;lt;-&lt;/code&gt; notation of Haskell, but both are available.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; MonadLetNotation.
&lt;span class=&quot;hljs-keyword&quot;&gt;Open&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Scope&lt;/span&gt; monad_scope.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, we define a notation to be able to define local, monadic
recursive functions using the &lt;code class=&quot;hljs&quot;&gt;mfix&lt;/code&gt; combinator of the &lt;code class=&quot;hljs&quot;&gt;MonadFix&lt;/code&gt;
typeclass.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Notation&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&apos;let_rec*&apos; f x &apos;:`&apos; p &apos;in&apos; q&quot;&lt;/span&gt; :`
  (&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; f :` mfix (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; f x `&amp;gt; p) &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; q)
    (&lt;span class=&quot;hljs-built_in&quot;&gt;at&lt;/span&gt; level &lt;span class=&quot;hljs-number&quot;&gt;61&lt;/span&gt;, x &lt;span class=&quot;hljs-built_in&quot;&gt;pattern&lt;/span&gt;, f name, q &lt;span class=&quot;hljs-built_in&quot;&gt;at&lt;/span&gt; next level, &lt;span class=&quot;hljs-built_in&quot;&gt;right&lt;/span&gt; associativity).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that &lt;code class=&quot;hljs&quot;&gt;mfix&lt;/code&gt; does /not/ check whether or not the defined function
will terminate (contrary to the &lt;code class=&quot;hljs&quot;&gt;fix&lt;/code&gt; keyword of Coq). This is
fortunate because in our case, we do not want our echo server to
converge, but rather to accept an infinite number of connections.&lt;/p&gt;
&lt;p&gt;We can demonstrate how this notation can be leveraged by defining a
generic TCP server, parameterized by a handler to deal with incoming
connections.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; tcp_srv `{Monad m, MonadFix m, MonadProc m, MonadSocket m}
    (handler : socket_descr -&amp;gt; m unit)
  : m unit :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt;* srv := open_socket &lt;span class=&quot;hljs-string&quot;&gt;&quot;127.0.0.1&quot;&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;8888&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt;
  listen srv;;

  let_rec* tcp_aux &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; :=
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt;* client := accept_connection srv &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt;* res := fork tt &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; res &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
    | &lt;span class=&quot;hljs-type&quot;&gt;Parent&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; =&amp;gt; close_socket client &amp;gt;&amp;gt;= tcp_aux
    | &lt;span class=&quot;hljs-type&quot;&gt;Child&lt;/span&gt; =&amp;gt;  handler client
    &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt;

  tcp_aux tt.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The handler for the echo server is straightforward: it just reads
incoming bytes from the socket, sends it back, and closes the socket.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; echo_handler `{Monad m, MonadSocket m} (sock : socket_descr)
  : m unit :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt;* msg := recv sock &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt;
  send sock msg;;
  close_socket sock.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Composing our generic TCP server with our echo handler gives us an
echo server.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; echo_server `{Monad m, MonadFix m, MonadProc m, MonadSocket m}
  : m unit :=
  tcp_srv echo_handler.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; has generated typeclasses for the impure primitives
of &lt;code class=&quot;hljs&quot;&gt;proc.mli&lt;/code&gt; and &lt;code class=&quot;hljs&quot;&gt;socket.mli&lt;/code&gt;, &lt;code class=&quot;hljs&quot;&gt;echo_server&lt;/code&gt; is polymorphic, and can
be instantiated for different monads. When it comes to extracting our
program, we will generally prefer the &lt;code class=&quot;hljs&quot;&gt;IO&lt;/code&gt; monad of &lt;code class=&quot;hljs&quot;&gt;coq-simple-io&lt;/code&gt;.
But we could also imagine verifying the client handler with FreeSpec,
or the generic TCP server with Interaction Trees (which support
diverging computations). Overall, we can have different verification
strategies for different parts of our program, by leveraging the most
relevant framework for each part, yet being able to extract it in an
efficient form.&lt;/p&gt;
&lt;p&gt;The next section shows how this last part is achieved using, once
again, a convenient stanza of dune.&lt;/p&gt;
&lt;h2&gt;Extracting and Building an Executable&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;hljs&quot;&gt;0.2&lt;/code&gt; version of the Coq-related stanzas of &lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; provides the
&lt;code class=&quot;hljs&quot;&gt;coq.extraction&lt;/code&gt; stanza, which can be used to build a Coq module
expected to generate &lt;code class=&quot;hljs&quot;&gt;ml&lt;/code&gt; files.&lt;/p&gt;
&lt;p&gt;In our case, we will write &lt;code class=&quot;hljs&quot;&gt;bin/echo.v&lt;/code&gt; to extract the &lt;code class=&quot;hljs&quot;&gt;echo_server&lt;/code&gt;
in a &lt;code class=&quot;hljs&quot;&gt;echo.ml&lt;/code&gt; module, and uses the &lt;code class=&quot;hljs&quot;&gt;executable&lt;/code&gt; stanza of &lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; to
get an executable from this file. To achieve this, the &lt;code class=&quot;hljs&quot;&gt;bin/dune&lt;/code&gt;
file simply requires these two stanzas.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-lisp&quot;&gt;(&lt;span class=&quot;hljs-name&quot;&gt;coq&lt;/span&gt;.extraction
  (&lt;span class=&quot;hljs-name&quot;&gt;prelude&lt;/span&gt; echo)
  (&lt;span class=&quot;hljs-name&quot;&gt;theories&lt;/span&gt; Echo)
  (&lt;span class=&quot;hljs-name&quot;&gt;extracted_modules&lt;/span&gt; echo))

(&lt;span class=&quot;hljs-name&quot;&gt;executable&lt;/span&gt;
  (&lt;span class=&quot;hljs-name&quot;&gt;name&lt;/span&gt; echo)
  (&lt;span class=&quot;hljs-name&quot;&gt;libraries&lt;/span&gt; ffi))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are almost done. We now need to write the &lt;code class=&quot;hljs&quot;&gt;echo.v&lt;/code&gt; module, which
mostly consists of (1) providing a &lt;code class=&quot;hljs&quot;&gt;MonadFix&lt;/code&gt; instance for the &lt;code class=&quot;hljs&quot;&gt;IO&lt;/code&gt;
monad, (2) using the &lt;code class=&quot;hljs&quot;&gt;IO.unsafe_run&lt;/code&gt; function to escape the &lt;code class=&quot;hljs&quot;&gt;IO&lt;/code&gt;
monad, (3) calling the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Extraction&lt;/span&gt;&lt;/code&gt; command to wrap it up.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; Coq &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Extraction&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; ExtLib &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; MonadFix.
&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; SimpleIO &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; SimpleIO.
&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; Echo &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Server.

&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; MonadFix_IO : MonadFix IO :=
  { mfix := @IO.fix_io }.

&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; main : io_unit :=
  IO.unsafe_run echo_server.

&lt;span class=&quot;hljs-keyword&quot;&gt;Extraction&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;echo.ml&quot;&lt;/span&gt; main.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since we are using the &lt;code class=&quot;hljs language-coq&quot;&gt;i63&lt;/code&gt; type (signed 63bits integers) of the
&lt;code class=&quot;hljs&quot;&gt;CoqFFI&lt;/code&gt; theory, and since &lt;code class=&quot;hljs language-coq&quot;&gt;i63&lt;/code&gt; is implemented under the hood with Coq
primitive integers, we &lt;em&gt;also&lt;/em&gt; need to provide a &lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;Uint63&lt;/span&gt;&lt;/code&gt; module with a
&lt;code class=&quot;hljs language-ocaml&quot;&gt;of_int&lt;/code&gt; function. Fortunately, this module is straightforward to
write.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; of_int x = x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And &lt;em&gt;voilà&lt;/em&gt;. A call to &lt;code class=&quot;hljs&quot;&gt;dune&lt;/code&gt; at the root of the repository will
build everything (Coq and OCaml alike). Starting the echo server
is as simple as&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot;&gt;dune &lt;span class=&quot;hljs-built_in&quot;&gt;exec&lt;/span&gt; bin/echo.exe
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And connecting to it can be achieved with a program like &lt;code class=&quot;hljs&quot;&gt;telnet&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-console&quot;&gt;&lt;span class=&quot;hljs-meta prompt_&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;language-bash&quot;&gt;telnet 127.0.0.1 8888&lt;/span&gt;
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is &apos;^]&apos;.
hello, echo server!
hello, echo server!
Connection closed by foreign host.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Appendix&lt;/h2&gt;
&lt;h3&gt;The &lt;code class=&quot;hljs&quot;&gt;Socket&lt;/code&gt; OCaml Module&lt;/h3&gt;
&lt;p&gt;There is not much to say, except that (as already stated) we use the
&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;Unix&lt;/span&gt;&lt;/code&gt; module to manipulate sockets, and we attach to each socket a
buffer to store incoming bytes.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; buffer_size = &lt;span class=&quot;hljs-number&quot;&gt;1024&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; socket_descr = {
  fd : &lt;span class=&quot;hljs-type&quot;&gt;Unix&lt;/span&gt;.file_descr;
  recv_buffer : &lt;span class=&quot;hljs-built_in&quot;&gt;bytes&lt;/span&gt;;
}

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; from_fd fd =
  &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; rbuff = &lt;span class=&quot;hljs-type&quot;&gt;Bytes&lt;/span&gt;.create buffer_size &lt;span class=&quot;hljs-keyword&quot;&gt;in&lt;/span&gt;
  { fd ` fd; recv_buffer ` rbuff }

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; open_socket hostname port =
  &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;Unix&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; addr = inet_addr_of_string hostname &lt;span class=&quot;hljs-keyword&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; fd = socket &lt;span class=&quot;hljs-type&quot;&gt;PF_INET&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;SOCK_STREAM&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;in&lt;/span&gt;
  setsockopt fd &lt;span class=&quot;hljs-type&quot;&gt;SO_REUSEADDR&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;;
  bind fd (&lt;span class=&quot;hljs-type&quot;&gt;ADDR_INET&lt;/span&gt; (addr, port));
  from_fd fd

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; listen sock = &lt;span class=&quot;hljs-type&quot;&gt;Unix&lt;/span&gt;.listen sock.fd &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; recv sock =
  &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; s = &lt;span class=&quot;hljs-type&quot;&gt;Unix&lt;/span&gt;.read sock.fd sock.recv_buffer &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; buffer_size &lt;span class=&quot;hljs-keyword&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;hljs-type&quot;&gt;Bytes&lt;/span&gt;.sub_string sock.recv_buffer &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; s

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; send sock msg =
  &lt;span class=&quot;hljs-type&quot;&gt;Unix&lt;/span&gt;.write_substring sock.fd msg &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; (&lt;span class=&quot;hljs-type&quot;&gt;String&lt;/span&gt;.length msg)

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; accept_connection sock =
  &lt;span class=&quot;hljs-type&quot;&gt;Unix&lt;/span&gt;.accept sock.fd |&amp;gt; fst |&amp;gt; from_fd

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; close_socket sock = &lt;span class=&quot;hljs-type&quot;&gt;Unix&lt;/span&gt;.close sock.fd
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The &lt;code class=&quot;hljs&quot;&gt;Proc&lt;/code&gt; OCaml Module&lt;/h3&gt;
&lt;p&gt;Thanks to the &lt;code class=&quot;hljs&quot;&gt;Unix&lt;/code&gt; module, the implementation is pretty straightforward.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; identity = &lt;span class=&quot;hljs-type&quot;&gt;Parent&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;int&lt;/span&gt; | &lt;span class=&quot;hljs-type&quot;&gt;Child&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; fork x =
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;Unix&lt;/span&gt;.fork x &lt;span class=&quot;hljs-keyword&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-type&quot;&gt;Child&lt;/span&gt;
  | x -&amp;gt; &lt;span class=&quot;hljs-type&quot;&gt;Parent&lt;/span&gt; x
&lt;/code&gt;&lt;/pre&gt;
        
      </description>
    </item>
    
    
    
    <item>
      <title>coqffi.1.0.0 In A Nutshell</title>
      <link>https://soap.coffee/~lthms/posts/Coqffi-1-0-0.html</link>
      <guid>https://soap.coffee/~lthms/posts/Coqffi-1-0-0.html</guid>
      <pubDate>December 10, 2020</pubDate>
      <description>
        
        &lt;h1&gt;&lt;code class=&quot;hljs&quot;&gt;coqffi.1.0.0&lt;/code&gt; In A Nutshell&lt;/h1&gt;&lt;div id=&quot;tags-list&quot;&gt;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coq.html&quot; class=&quot;tag hover-lemon&quot; marked=&quot;&quot;&gt;coq&lt;/a&gt; &lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/ocaml.html&quot; class=&quot;tag hover-sky&quot; marked=&quot;&quot;&gt;ocaml&lt;/a&gt; &lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coqffi.html&quot; class=&quot;tag hover-lavender&quot; marked=&quot;&quot;&gt;coqffi&lt;/a&gt; &lt;/div&gt;
&lt;p&gt;For each entry of a &lt;code class=&quot;hljs&quot;&gt;cmi&lt;/code&gt; file (a &lt;em&gt;compiled&lt;/em&gt; &lt;code class=&quot;hljs&quot;&gt;mli&lt;/code&gt; file), &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;
tries to generate an equivalent (from the extraction mechanism
perspective) Coq definition. In this article, we walk through how
&lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; works.&lt;/p&gt;
&lt;p&gt;Note that we do not dive into the vernacular commands &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;
generates. They are of no concern for users of &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;h3&gt;Requirements&lt;/h3&gt;
&lt;p&gt;The latest version of &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; (&lt;code class=&quot;hljs&quot;&gt;1.0.0~beta8&lt;/code&gt;)
is compatible with OCaml &lt;code class=&quot;hljs&quot;&gt;4.08&lt;/code&gt; up to &lt;code class=&quot;hljs&quot;&gt;4.14&lt;/code&gt;, and Coq &lt;code class=&quot;hljs&quot;&gt;8.12&lt;/code&gt; up top
&lt;code class=&quot;hljs&quot;&gt;8.13&lt;/code&gt;.  If you want to use &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;, but have incompatible
requirements of your own, feel free to
&lt;a href=&quot;https://github.com/coq-community/coqffi/issues&quot; class=&quot;hover-lemon&quot; marked=&quot;&quot;&gt;submit an issue&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Installing &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The recommended way to install &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; is through the
&lt;a href=&quot;https://coq.inria.fr/opam/www&quot; class=&quot;hover-rose&quot; marked=&quot;&quot;&gt;Opam Coq Archive&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#external-link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;, in the &lt;code class=&quot;hljs&quot;&gt;released&lt;/code&gt;
repository.  If you haven’t activated this repository yet, you can use the
following bash command.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot;&gt;opam repo add coq-released https://coq.inria.fr/opam/released
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, installing &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; is as simple as&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot;&gt;opam install coq-coqffi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also get the source from &lt;a href=&quot;https://github.com/coq-community/coqffi&quot; class=&quot;hover-sky&quot; marked=&quot;&quot;&gt;the upstream &lt;code class=&quot;hljs&quot;&gt;git&lt;/code&gt;
repository&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;. The &lt;code class=&quot;hljs&quot;&gt;README&lt;/code&gt; provides the
necessary pieces of information to build it from source.&lt;/p&gt;
&lt;h3&gt;Additional Dependencies&lt;/h3&gt;
&lt;p&gt;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. &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; currently
supports two of them:
&lt;a href=&quot;https://github.com/Lysxia/coq-simple-io&quot; class=&quot;hover-coral&quot; marked=&quot;&quot;&gt;&lt;code class=&quot;hljs&quot;&gt;coq-simple-io&lt;/code&gt;&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt; and
&lt;a href=&quot;https://github.com/ANSSI-FR/FreeSpec&quot; class=&quot;hover-mint&quot; marked=&quot;&quot;&gt;FreeSpec&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;. It is also possible to use it
with &lt;a href=&quot;https://github.com/DeepSpec/InteractionTrees&quot; class=&quot;hover-rose&quot; marked=&quot;&quot;&gt;Interaction Trees&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;, albeit
in a less direct manner.&lt;/p&gt;
&lt;h3&gt;Primitive Types&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; supports a set of primitive types, &lt;em&gt;i.e.&lt;/em&gt;, 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 &lt;code class=&quot;hljs&quot;&gt;Import&lt;/code&gt; statements are
generated too).&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OCaml type&lt;/th&gt;
&lt;th&gt;Coq type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;bool&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;hljs&quot;&gt;Coq.Init.Datatypes.bool&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;char&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;hljs&quot;&gt;Coq.Strings.Ascii.ascii&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;int&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;hljs&quot;&gt;CoqFFI.Data.Int.i63&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;list&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;hljs&quot;&gt;Coq.Init.Datatypes.list a&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;Seq&lt;/span&gt;.t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;hljs&quot;&gt;CoqFFI.Data.Seq.t&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; option&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;hljs&quot;&gt;Coq.Init.Datatypes.option a&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;(&lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt;, &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;e&lt;/span&gt;) result&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;hljs&quot;&gt;Coq.Init.Datatypes.sum&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;hljs&quot;&gt;Coq.Strings.String.string&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;unit&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;hljs&quot;&gt;Coq.Init.Datatypes.unit&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;exn&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code class=&quot;hljs&quot;&gt;CoqFFI.Exn&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The &lt;code class=&quot;hljs language-coq&quot;&gt;i63&lt;/code&gt; type is introduced by the &lt;code class=&quot;hljs language-coq&quot;&gt;CoqFFI&lt;/code&gt; theory to provide
signed primitive integers to Coq users. They are implemented on top of the
(unsigned) Coq native integers introduced in Coq &lt;code class=&quot;hljs&quot;&gt;8.13&lt;/code&gt;. The &lt;code class=&quot;hljs&quot;&gt;i63&lt;/code&gt; type will be
deprecated once the support for &lt;a href=&quot;https://github.com/coq/coq/pull/13559&quot; class=&quot;hover-peach&quot; marked=&quot;&quot;&gt;signed primitive
integers&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt; is implemented&lt;label for=&quot;fn1&quot; class=&quot;sidenote-number margin-toggle&quot;&gt;&lt;/label&gt;&lt;input id=&quot;fn1&quot; type=&quot;checkbox&quot; class=&quot;margin-toggle&quot;&gt;&lt;span class=&quot;note-right sidenote note&quot;&gt;&lt;span class=&quot;footnote-p&quot;&gt;This is actually one of the sources of incompatibility of &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;
with most recent versions of Coq. &lt;/span&gt;
&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;When processing the entries of a given interface model, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; will
check that they only use these types, or types introduced by the
interface module itself.&lt;/p&gt;
&lt;p&gt;Sometimes, you may encounter a situation where you have two interface
modules &lt;code class=&quot;hljs&quot;&gt;b.mli&lt;/code&gt; and &lt;code class=&quot;hljs&quot;&gt;b.mli&lt;/code&gt;, such that &lt;code class=&quot;hljs&quot;&gt;b.mli&lt;/code&gt; uses a type introduced
in &lt;code class=&quot;hljs&quot;&gt;a.mli&lt;/code&gt;.  To deal with this scenario, you can use the &lt;code class=&quot;hljs&quot;&gt;--witness&lt;/code&gt;
flag to generate &lt;code class=&quot;hljs&quot;&gt;A.v&lt;/code&gt;.  This will tell &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; to also generate
&lt;code class=&quot;hljs&quot;&gt;A.ffi&lt;/code&gt;; this file can then be used when generating &lt;code class=&quot;hljs&quot;&gt;B.v&lt;/code&gt; thanks to
the &lt;code class=&quot;hljs&quot;&gt;-I&lt;/code&gt; option.  Furthermore, for &lt;code class=&quot;hljs&quot;&gt;B.v&lt;/code&gt; to compile the &lt;code class=&quot;hljs&quot;&gt;--require&lt;/code&gt;
option needs to be used to ensure the &lt;code class=&quot;hljs&quot;&gt;A&lt;/code&gt; Coq library (&lt;code class=&quot;hljs&quot;&gt;A.v&lt;/code&gt;) is
required.&lt;/p&gt;
&lt;p&gt;To give a more concrete example, given ~a.mli~&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; t
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and &lt;code class=&quot;hljs&quot;&gt;b.mli&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; a = &lt;span class=&quot;hljs-type&quot;&gt;A&lt;/span&gt;.t
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To generate &lt;code class=&quot;hljs&quot;&gt;A.v&lt;/code&gt;, we can use the following commands:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot;&gt;ocamlc a.mli
coqffi --witness -o A.v a.cmi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which would generate the following axiom for &lt;code class=&quot;hljs&quot;&gt;t&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; t : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, generating &lt;code class=&quot;hljs&quot;&gt;B.v&lt;/code&gt; can be achieved as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot;&gt;ocamlc b.mli
coqffi -I A.ffi -ftransparent-types -r A -o B.v b.cmi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which results in the following output for &lt;code class=&quot;hljs&quot;&gt;v&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; A.

&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; u : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; := A.t.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Code Generation&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; 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.&lt;/p&gt;
&lt;h3&gt;Types&lt;/h3&gt;
&lt;p&gt;By default, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; generates axiomatized definitions for each type defined in
a &lt;code class=&quot;hljs&quot;&gt;.cmi&lt;/code&gt; file. This means that &lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; t&lt;/code&gt; becomes &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; t : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;&lt;/code&gt;.
Polymorphism is supported, &lt;em&gt;i.e.&lt;/em&gt;, &lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; t&lt;/code&gt; becomes &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; t : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (a : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;), &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It is possible to provide a “model” for a type using the &lt;code class=&quot;hljs&quot;&gt;coq_model&lt;/code&gt;
annotation, for instance, for reasoning purposes. That is, we can specify
that a type is equivalent to a &lt;code class=&quot;hljs&quot;&gt;list&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; t [@@coq_model &lt;span class=&quot;hljs-string&quot;&gt;&quot;list&quot;&lt;/span&gt;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This generates the following Coq definition.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; t : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (a : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;), &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; := list.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is important to be careful when using the =coq_model= annotation. More
precisely, the fact that &lt;code class=&quot;hljs&quot;&gt;t&lt;/code&gt; is a &lt;code class=&quot;hljs&quot;&gt;list&lt;/code&gt; in the “Coq universe” shall not be
used while the implementation phase, only the verification phase.&lt;/p&gt;
&lt;p&gt;Unnamed polymorphic type parameters are also supported. In presence of
such parameters, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; will find it a name that is not already
used. For instance,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; (_, &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt;) ast
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; ast : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (b : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) (a : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;), &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; has got an experimental feature called &lt;code class=&quot;hljs&quot;&gt;transparent-types&lt;/code&gt;
(enabled by using the &lt;code class=&quot;hljs&quot;&gt;-ftransparent-types&lt;/code&gt; command-line argument). If the type
definition is given in the module interface, then &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; tries to generate
an equivalent definition in Coq. For instance,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; llist =
  | &lt;span class=&quot;hljs-type&quot;&gt;LCons&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; * (&lt;span class=&quot;hljs-built_in&quot;&gt;unit&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; llist)
  | &lt;span class=&quot;hljs-type&quot;&gt;LNil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; llist (a : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
| &lt;span class=&quot;hljs-type&quot;&gt;LCons&lt;/span&gt; (x0 : a) (x1 : unit -&amp;gt; llist a) : llist a
| &lt;span class=&quot;hljs-type&quot;&gt;LNil&lt;/span&gt; : llist a.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mutually recursive types are supported, so&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; even = &lt;span class=&quot;hljs-type&quot;&gt;Zero&lt;/span&gt; | &lt;span class=&quot;hljs-type&quot;&gt;ESucc&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;of&lt;/span&gt; odd
&lt;span class=&quot;hljs-keyword&quot;&gt;and&lt;/span&gt; odd = &lt;span class=&quot;hljs-type&quot;&gt;OSucc&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;of&lt;/span&gt; even
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; odd : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
| &lt;span class=&quot;hljs-type&quot;&gt;OSucc&lt;/span&gt; (x0 : even) : odd
&lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; even : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
| &lt;span class=&quot;hljs-type&quot;&gt;Zero&lt;/span&gt; : even
| &lt;span class=&quot;hljs-type&quot;&gt;ESucc&lt;/span&gt; (x0 : odd) : even.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; supports alias types, as suggested in this write-up
when we discuss witness files.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;hljs&quot;&gt;transparent-types&lt;/code&gt; feature is &lt;strong&gt;experimental&lt;/strong&gt;, 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
&lt;a href=&quot;https://coq.inria.fr/refman/language/core/inductive.html#positivity-condition&quot; class=&quot;hover-rose&quot; marked=&quot;&quot;&gt;positivity
condition&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#external-link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;
is satisfied.&lt;/p&gt;
&lt;h3&gt;Pure values&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; decides whether or not a given OCaml value is pure or impure
with the following heuristics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Constants are pure&lt;/li&gt;
&lt;li&gt;Functions are impure by default&lt;/li&gt;
&lt;li&gt;Functions with a &lt;code class=&quot;hljs&quot;&gt;coq_model&lt;/code&gt; annotation are pure&lt;/li&gt;
&lt;li&gt;Functions marked with the &lt;code class=&quot;hljs&quot;&gt;pure&lt;/code&gt; annotation are pure&lt;/li&gt;
&lt;li&gt;If the &lt;code class=&quot;hljs&quot;&gt;pure-module&lt;/code&gt; feature is enabled (&lt;code class=&quot;hljs&quot;&gt;-fpure-module&lt;/code&gt;), then synchronous
functions (which do not live inside the
&lt;a href=&quot;https://ocsigen.org/lwt/5.3.0/manual/manual&quot; class=&quot;hover-periwinkle&quot; marked=&quot;&quot;&gt;~Lwt~&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#external-link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt; monad) are pure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Similarly to types, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; generates axioms (or definitions if the
&lt;code class=&quot;hljs&quot;&gt;coq_model&lt;/code&gt; annotation is used) for pure values. Then,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; unpack : &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; -&amp;gt; (&lt;span class=&quot;hljs-built_in&quot;&gt;char&lt;/span&gt; * &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;) option [@@pure]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;Axiom&lt;/span&gt; unpack : &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; -&amp;gt; option (ascii * &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Polymorphic values are supported.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; map : (&lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;b&lt;/span&gt;) -&amp;gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;list&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;b&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;list&lt;/span&gt; [@@pure]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; map : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (a : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) (b : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;), (a -&amp;gt; b) -&amp;gt; list a -&amp;gt; list b.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, unnamed polymorphic typse are supported, so&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; ast_to_string : _ ast -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; [@@pure]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; ast_to_string : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (a : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;), string.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Impure Primitives&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; reserves a special treatment for /impure/ OCaml functions.
Impurity is usually handled in pure programming languages by means of
monads, and &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; is no exception to the rule.&lt;/p&gt;
&lt;p&gt;Given the set of impure primitives declared in an interface module,
&lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; will (1) generate a typeclass which gathers these primitives,
and (2) generate instances of this typeclass for supported backends.&lt;/p&gt;
&lt;p&gt;We illustrate the rest of this section with the following impure
primitives.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; echo : &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;unit&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; scan : &lt;span class=&quot;hljs-built_in&quot;&gt;unit&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where &lt;code class=&quot;hljs&quot;&gt;echo&lt;/code&gt; allows writing something the standard output, and &lt;code class=&quot;hljs&quot;&gt;scan&lt;/code&gt;
to read the standard input.&lt;/p&gt;
&lt;p&gt;Assuming the processed module interface is named &lt;code class=&quot;hljs&quot;&gt;console.mli&lt;/code&gt;, the
following Coq typeclass is generated.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Class&lt;/span&gt; MonadConsole (m : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) := { echo : string -&amp;gt; m unit
                                         ; scan : unit -&amp;gt; m string
                                         }.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using this typeclass and with the additional support of an additional
&lt;code class=&quot;hljs&quot;&gt;Monad&lt;/code&gt; typeclass, we can specify impure computations which interacts
with the console. For instance, with the support of &lt;code class=&quot;hljs&quot;&gt;ExtLib&lt;/code&gt;, one can
write.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; pipe `{Monad m, MonadConsole m} : m unit :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt;* msg := scan () &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt;
  echo msg.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is no canonical way to model impurity in Coq, but over the years
several frameworks have been released to tackle this challenge.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; provides three features related to impure primitives.&lt;/p&gt;
&lt;h4&gt;&lt;code class=&quot;hljs&quot;&gt;simple-io&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;When this feature is enabled, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; generates an instance of the
typeclass for the =IO= monad introduced in the &lt;code class=&quot;hljs&quot;&gt;coq-simple-io&lt;/code&gt; package&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; io_echo : string -&amp;gt; IO unit.
&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; io_scan : unit -&amp;gt; IO string.

&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; IO_MonadConsole : MonadConsole IO := { echo := io_echo
                                              ; scan := io_scan
                                              }.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is enabled by default, but can be disabled using the
&lt;code class=&quot;hljs&quot;&gt;-fno-simple-io&lt;/code&gt; command-line argument.&lt;/p&gt;
&lt;h4&gt;&lt;code class=&quot;hljs&quot;&gt;interface&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;When this feature is enabled, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; generates an inductive type which
describes the set of primitives available, to be used with frameworks like
&lt;a href=&quot;https://github.com/lthms/FreeSpec&quot; class=&quot;hover-rose&quot; marked=&quot;&quot;&gt;FreeSpec&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt; or &lt;a href=&quot;https://github.com/DeepSpec/InteractionTrees&quot; class=&quot;hover-periwinkle&quot; marked=&quot;&quot;&gt;Interactions
Trees&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; CONSOLE : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
| &lt;span class=&quot;hljs-type&quot;&gt;Echo&lt;/span&gt; : string -&amp;gt; CONSOLE unit
| &lt;span class=&quot;hljs-type&quot;&gt;Scan&lt;/span&gt; : unit -&amp;gt; CONSOLE string.

&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; inj_echo `{Inject CONSOLE m} (x0 : string) : m unit :=
  inject (Echo x0).

&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; inj_scan `{Inject CONSOLE m} (x0 : unit) : m string :=
  inject (Scan x0).

&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; Inject_MonadConsole `{Inject CONSOLE m} : MonadConsole m :=
  { echo := inj_echo
  ; scan := inj_scan
  }.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Providing an instance of the form &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; i, Inject i M&lt;/code&gt; is enough for
your monad &lt;code class=&quot;hljs&quot;&gt;M&lt;/code&gt; to be compatible with this feature&lt;label for=&quot;fn2&quot; class=&quot;sidenote-number margin-toggle&quot;&gt;&lt;/label&gt;&lt;input id=&quot;fn2&quot; type=&quot;checkbox&quot; class=&quot;margin-toggle&quot;&gt;&lt;span class=&quot;note-left sidenote note&quot;&gt;&lt;span class=&quot;footnote-p&quot;&gt;See for instance &lt;a href=&quot;https://github.com/lthms/FreeSpec/blob/master/theories/FFI/FFI.v&quot; class=&quot;hover-lemon&quot; marked=&quot;&quot;&gt;how FreeSpec implements
it&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;). &lt;/span&gt;
&lt;/span&gt;.&lt;/p&gt;
&lt;h4&gt;&lt;code class=&quot;hljs&quot;&gt;freespec&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;When this feature in enabled, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; generates a semantics for the
inductive type generated by the &lt;code class=&quot;hljs&quot;&gt;interface&lt;/code&gt; feature.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; unsafe_echo : string -&amp;gt; unit.
&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; unsafe_scan : uint -&amp;gt; string.

&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; console_unsafe_semantics : semantics CONSOLE :=
  bootstrap (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; a e =&amp;gt;
    local &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; e &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; CONSOLE a &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; a &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
          | &lt;span class=&quot;hljs-type&quot;&gt;Echo&lt;/span&gt; x0 =&amp;gt; unsafe_echo x0
          | &lt;span class=&quot;hljs-type&quot;&gt;Scan&lt;/span&gt; x0 =&amp;gt; unsafe_scan x0
          &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;).
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Asynchronous Primitives&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; also reserves a special treatment for &lt;em&gt;asynchronous&lt;/em&gt;
primitives —&lt;em&gt;i.e.&lt;/em&gt;, functions which live inside the &lt;code class=&quot;hljs&quot;&gt;Lwt&lt;/code&gt; monad— when
the &lt;code class=&quot;hljs&quot;&gt;lwt&lt;/code&gt; feature is enabled.&lt;/p&gt;
&lt;p&gt;The treatment is very analogous to the one for impure primitives: (1)
a typeclass is generated (with the &lt;code class=&quot;hljs&quot;&gt;_Async&lt;/code&gt; suffix), and (2) an
instance for the &lt;code class=&quot;hljs&quot;&gt;Lwt&lt;/code&gt; monad is generated. Besides, an instance for
the “synchronous” primitives is also generated for &lt;code class=&quot;hljs&quot;&gt;Lwt&lt;/code&gt;. If the
&lt;code class=&quot;hljs&quot;&gt;interface&lt;/code&gt; 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).&lt;/p&gt;
&lt;p&gt;By default, the type of the &lt;code class=&quot;hljs&quot;&gt;Lwt&lt;/code&gt; monad is &lt;code class=&quot;hljs&quot;&gt;Lwt.t&lt;/code&gt;. You can override
this setting using the &lt;code class=&quot;hljs&quot;&gt;--lwt-alias&lt;/code&gt; option.  This can be useful when
you are using an alias type in place of &lt;code class=&quot;hljs&quot;&gt;Lwt.t&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Exceptions&lt;/h3&gt;
&lt;p&gt;OCaml features an exception mechanism. Developers can define their
own exceptions using the &lt;code class=&quot;hljs&quot;&gt;exception&lt;/code&gt; keyword, whose syntax is similar
to the constructors’ definition. For instance,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;exception&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;int&lt;/span&gt; * &lt;span class=&quot;hljs-built_in&quot;&gt;bool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;introduces a new exception &lt;code class=&quot;hljs&quot;&gt;Foo&lt;/code&gt; which takes two parameters of type &lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;int&lt;/span&gt;&lt;/code&gt; and
&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;bool&lt;/span&gt;&lt;/code&gt;. &lt;code class=&quot;hljs&quot;&gt;Foo (x, y)&lt;/code&gt; constructs of value of type &lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;exn&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For each new exception introduced in an OCaml module, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;
generates (1) a so-called “proxy type,” and (2) conversion functions
to and from this type.&lt;/p&gt;
&lt;p&gt;Coming back to our example, the “proxy type” generates by &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; is&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; FooExn : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
| &lt;span class=&quot;hljs-type&quot;&gt;MakeFooExn&lt;/span&gt; (x0 : i63) (x1 : bool) : FooExn.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; generates conversion functions.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; exn_of_foo : FooExn -&amp;gt; exn.
&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; foo_of_exn : exn -&amp;gt; option FooExn.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Besides, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; also generates an instance for the &lt;code class=&quot;hljs&quot;&gt;Exn&lt;/code&gt; typeclass
provided by the &lt;code class=&quot;hljs&quot;&gt;CoqFFI&lt;/code&gt; theory:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; FooExn_Exn : Exn FooExn :=
  { to_exn := exn_of_foo
  ; of_exn := foo_of_exn
  }.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Under the hood, &lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;exn&lt;/span&gt;&lt;/code&gt; is an
&lt;a href=&quot;https://caml.inria.fr/pub/docs/manual-ocaml/extensiblevariants.html&quot; class=&quot;hover-lavender&quot; marked=&quot;&quot;&gt;extensible
datatype&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#external-link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;,
and how &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; supports it will probably be generalized in future releases.&lt;/p&gt;
&lt;p&gt;Finally, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; 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 explicitly, using the
=may_raise= annotation. In such a case, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; will change the
return type of the function to use the =sum= Coq inductive type.&lt;/p&gt;
&lt;p&gt;For instance,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; from_option : &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; option -&amp;gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; [@@may_raise] [@@pure]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; from_option : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (a : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;), option a -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt; a exn.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Modules&lt;/h3&gt;
&lt;p&gt;Lastly, &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; supports OCaml modules described within &lt;code class=&quot;hljs&quot;&gt;mli&lt;/code&gt; files,
when they are specified as &lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;T&lt;/span&gt; : &lt;span class=&quot;hljs-keyword&quot;&gt;sig&lt;/span&gt; ... &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;. For instance,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;T&lt;/span&gt; : &lt;span class=&quot;hljs-keyword&quot;&gt;sig&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; t

  &lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; to_string : t -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; [@@pure]
&lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Module&lt;/span&gt; T.
  &lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; t : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;.

  &lt;span class=&quot;hljs-keyword&quot;&gt;Axiom&lt;/span&gt; to_string : t -&amp;gt; string.
&lt;span class=&quot;hljs-keyword&quot;&gt;End&lt;/span&gt; T.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As of now, the following construction is unfortunately &lt;em&gt;not&lt;/em&gt;
supported, and will be ignored by &lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; = &lt;span class=&quot;hljs-keyword&quot;&gt;sig&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; t

  &lt;span class=&quot;hljs-keyword&quot;&gt;val&lt;/span&gt; to_string : t -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; [@@pure]
&lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;T&lt;/span&gt; : &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Moving Forward&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; comes with a comprehensive man page. In addition, the
interested reader can proceed to the next article of this series,
which explains how &lt;a href=&quot;/~lthms/posts/CoqffiEcho.html&quot; class=&quot;hover-periwinkle&quot; marked=&quot;&quot;&gt;&lt;code class=&quot;hljs&quot;&gt;coqffi&lt;/code&gt; can be used to easily implement an echo
server in Coq&lt;/a&gt;.&lt;/p&gt;
        
      </description>
    </item>
    
    
    
    <item>
      <title>Pattern Matching on Types and Contexts</title>
      <link>https://soap.coffee/~lthms/posts/LtacPatternMatching.html</link>
      <guid>https://soap.coffee/~lthms/posts/LtacPatternMatching.html</guid>
      <pubDate>August 28, 2020</pubDate>
      <description>
        
        &lt;h1&gt;Pattern Matching on Types and Contexts&lt;/h1&gt;&lt;div id=&quot;tags-list&quot;&gt;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coq.html&quot; class=&quot;tag hover-peach&quot; marked=&quot;&quot;&gt;coq&lt;/a&gt; &lt;/div&gt;
&lt;p&gt;In the &lt;a href=&quot;/~lthms/posts/LtacMetaprogramming.html&quot; class=&quot;hover-mint&quot; marked=&quot;&quot;&gt;a previous article&lt;/a&gt; of our series on
Ltac, we have shown how tactics allow for constructing Coq terms incrementally.
Ltac programs (“proof scripts”) generate terms, and the shape of said terms can
be very different regarding the initial context. For instance, &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; x&lt;/code&gt; will refine the current goal by using an inductive principle dedicated to
the type of &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is possible because Ltac allows for pattern matching on types and
contexts. In this article, we give a short introduction on this feature of
key importance.&lt;/p&gt;
&lt;h2&gt;To &lt;code class=&quot;hljs language-coq&quot;&gt;lazymatch&lt;/code&gt; or to &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt;&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Gallina provides one pattern matching construction, whose semantics is always
the same: for a given term, the first pattern to match will always be selected.
On the contrary, Ltac provides several pattern matching constructions with
different semantics. This key difference has probably been motivated because
Ltac is not a total language: a tactic may not always succeed.&lt;/p&gt;
&lt;p&gt;Ltac programmers can use &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt;&lt;/code&gt; or &lt;code class=&quot;hljs language-coq&quot;&gt;lazymatch&lt;/code&gt;. One the one hand,
with &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt;&lt;/code&gt;, if one pattern matches, but the branch body fails, Coq will
backtrack and try the next branch. On the other hand, &lt;code class=&quot;hljs language-coq&quot;&gt;lazymatch&lt;/code&gt; will
stop with an error.&lt;/p&gt;
&lt;p&gt;So, for instance, the two following tactics will print two different messages:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Ltac&lt;/span&gt; match_failure :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; goal &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt;
    =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;fail&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;fail in first branch&quot;&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt;
    =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;fail&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;fail in second branch&quot;&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Ltac&lt;/span&gt; lazymatch_failure :=
  lazymatch goal &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt;
    =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;fail&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;fail in first branch&quot;&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt;
    =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;fail&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;fail in second branch&quot;&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can try that quite easily by starting a dumb goal (eg. &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Goal&lt;/span&gt; (True).&lt;/code&gt;)
and call our tactic. For &lt;code class=&quot;hljs language-coq&quot;&gt;match_failure&lt;/code&gt;, we get:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;Ltac call to &quot;match_failure&quot; failed.
Error: Tactic failure: fail in second branch.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the other hand, for &lt;code class=&quot;hljs language-coq&quot;&gt;lazymatch_failure&lt;/code&gt;, we get:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;Ltac call to &quot;match_failure&apos;&quot; failed.
Error: Tactic failure: fail in first branch.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Moreover, pattern matching allows for matching over &lt;em&gt;patterns&lt;/em&gt;, not just
constants. Here, Ltac syntax differs from Gallina’s. In Gallina, if a
variable name is used in a pattern, Gallina creates a new variable in the
scope of the related branch. If a variable with the same name already
existed, it is shadowed. On the contrary, in Ltac, using a variable name
as-is in a pattern implies an equality check.&lt;/p&gt;
&lt;p&gt;To illustrate this difference, we can take the example of the following
tactic.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Ltac&lt;/span&gt; successive x y :=
  lazymatch y &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; x =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;idtac&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;fail&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;successive x y&lt;/code&gt; will fail if &lt;code class=&quot;hljs language-coq&quot;&gt;y&lt;/code&gt; is not the successor of
&lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt;. On the contrary, the “syntactically equivalent” function in Gallina
will exhibit a totally different behavior.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; successor (x y : nat) : bool :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; y &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; x =&amp;gt; true
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; =&amp;gt; false
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the first branch of the pattern match is systematically selected when
&lt;code class=&quot;hljs language-coq&quot;&gt;y&lt;/code&gt; is not &lt;code class=&quot;hljs language-coq&quot;&gt;O&lt;/code&gt;, and in this branch, the argument &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; is shadowed by the
predecessor of &lt;code class=&quot;hljs language-coq&quot;&gt;y&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For Ltac to adopt a behavior similar to Gallina, the &lt;code class=&quot;hljs language-coq&quot;&gt;?&lt;/code&gt; prefix shall be
used. For instance, the following tactic will check whether its argument
has a known successor, prints it if it does, or fail otherwise.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Ltac&lt;/span&gt; print_pred_or_zero x :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; ?x =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;idtac&lt;/span&gt; x
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;fail&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the one hand, &lt;code class=&quot;hljs language-coq&quot;&gt;print_pred_or_zero &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;&lt;/code&gt; will print &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;&lt;/code&gt;. On the
other hand, if there exists a variable &lt;code class=&quot;hljs language-coq&quot;&gt;x : nat&lt;/code&gt; in the context, calling
&lt;code class=&quot;hljs language-coq&quot;&gt;print_pred_or_zero x&lt;/code&gt; will fail, since the exact value of &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; is
not known.&lt;/p&gt;
&lt;h3&gt;Pattern Matching on Types with &lt;code class=&quot;hljs language-coq&quot;&gt;type of&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code class=&quot;hljs language-coq&quot;&gt;type of&lt;/code&gt; operator can be used in conjunction to pattern matching to
generate different terms according to the type of a variable. We could
leverage this to reimplement &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt;&lt;/code&gt; for instance.&lt;/p&gt;
&lt;p&gt;As an example, we propose the following &lt;code class=&quot;hljs language-coq&quot;&gt;not_nat&lt;/code&gt; tactic which, given an
argument &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt;, fails if &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; is of type &lt;code class=&quot;hljs language-coq&quot;&gt;nat&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Ltac&lt;/span&gt; not_nat x :=
  lazymatch type of x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;nat&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;fail&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;argument is of type nat&quot;&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;idtac&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this definition, &lt;code class=&quot;hljs language-coq&quot;&gt;not_nat true&lt;/code&gt; succeeds since &lt;code class=&quot;hljs language-coq&quot;&gt;true&lt;/code&gt; is of
type &lt;code class=&quot;hljs language-coq&quot;&gt;bool&lt;/code&gt;, and &lt;code class=&quot;hljs language-coq&quot;&gt;not_nat O&lt;/code&gt; since &lt;code class=&quot;hljs language-coq&quot;&gt;O&lt;/code&gt; encodes &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; in
&lt;code class=&quot;hljs language-coq&quot;&gt;nat&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can also use the &lt;code class=&quot;hljs language-coq&quot;&gt;?&lt;/code&gt; prefix to write true pattern. For instance, the
following tactic will fail if the type of its supplied argument has at least
one parameter.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Ltac&lt;/span&gt; not_param_type x :=
  lazymatch type of x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;?f&lt;/span&gt; ?a =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;fail&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;argument is of type with parameter&quot;&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;idtac&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both &lt;code class=&quot;hljs language-coq&quot;&gt;not_param_type (@nil nat)&lt;/code&gt; of type &lt;code class=&quot;hljs language-coq&quot;&gt;list nat&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;@eq_refl nat &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;/code&gt; of type &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;/code&gt; fail, but &lt;code class=&quot;hljs language-coq&quot;&gt;not_param_type &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;/code&gt; of type
&lt;code class=&quot;hljs language-coq&quot;&gt;nat&lt;/code&gt; succeeds. *)&lt;/p&gt;
&lt;h2&gt;Pattern Matching on the Context with &lt;code class=&quot;hljs language-coq&quot;&gt;goal&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Lastly, we discuss how Ltac allows for inspecting the context (&lt;em&gt;i.e.&lt;/em&gt;, the
hypotheses and the goal) using the &lt;code class=&quot;hljs language-coq&quot;&gt;goal&lt;/code&gt; keyword.&lt;/p&gt;
&lt;p&gt;For instance, we propose a naive implementation of the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;subst&lt;/span&gt;&lt;/code&gt; tactic
as follows.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Ltac&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;subst&lt;/span&gt;&apos; :=
  &lt;span class=&quot;hljs-built_in&quot;&gt;repeat&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; goal &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
    | &lt;span class=&quot;hljs-type&quot;&gt;H&lt;/span&gt; :  ?x = &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; |&lt;span class=&quot;hljs-type&quot;&gt;- context&lt;/span&gt;[?x]
      =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;repeat&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; H; &lt;span class=&quot;hljs-built_in&quot;&gt;clear&lt;/span&gt; H
    &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With &lt;code class=&quot;hljs language-coq&quot;&gt;goal&lt;/code&gt;, patterns are of the form &lt;code class=&quot;hljs language-coq&quot;&gt;H : (&lt;span class=&quot;hljs-built_in&quot;&gt;pattern&lt;/span&gt;), ... |&lt;span class=&quot;hljs-type&quot;&gt;- (pattern&lt;/span&gt;)&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;At the left side of &lt;code class=&quot;hljs language-coq&quot;&gt;|&lt;span class=&quot;hljs-type&quot;&gt;-&lt;/span&gt;&lt;/code&gt;, we match on hypotheses. Beware that
contrary to variable names in pattern, hypothesis names behaves as in
Gallina (i.e., fresh binding, shadowing, etc.). In the branch, we are
looking for equations, i.e., a hypothesis of the form &lt;code class=&quot;hljs language-coq&quot;&gt;?x = &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;At the right side of &lt;code class=&quot;hljs language-coq&quot;&gt;|&lt;span class=&quot;hljs-type&quot;&gt;-&lt;/span&gt;&lt;/code&gt;, we match on the goal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In both cases, Ltac makes available an interesting operator,
&lt;code class=&quot;hljs language-coq&quot;&gt;context[(&lt;span class=&quot;hljs-built_in&quot;&gt;pattern&lt;/span&gt;)&lt;/code&gt;], which is satisfied if &lt;code class=&quot;hljs language-coq&quot;&gt;(&lt;span class=&quot;hljs-built_in&quot;&gt;pattern&lt;/span&gt;)&lt;/code&gt; appears somewhere in
the object we are pattern matching against. So, the branch of the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt;&lt;/code&gt;
reads as follows: we are looking for an equation &lt;code class=&quot;hljs language-coq&quot;&gt;H&lt;/code&gt; which specifies the
value of an object &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; which appears in the goal. If such an equation
exists, &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;subst&lt;/span&gt;&apos;&lt;/code&gt; tries to &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; x&lt;/code&gt; as many times as possible.&lt;/p&gt;
&lt;p&gt;This implementation of &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;subst&lt;/span&gt;&apos;&lt;/code&gt; is very fragile, and will not work if the
equation is of the form &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; = ?x&lt;/code&gt;, and it may behave poorly if we have
“transitive equations”, such as there exists hypotheses &lt;code class=&quot;hljs language-coq&quot;&gt;?x = ?y&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;?y = &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;&lt;/code&gt;. Motivated readers may be interested in proposing a more robust
implementation of &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;subst&lt;/span&gt;&apos;&lt;/code&gt;.&lt;/p&gt;
        
      </description>
    </item>
    
    
    
    <item>
      <title>Ltac is an Imperative Metaprogramming Language</title>
      <link>https://soap.coffee/~lthms/posts/LtacMetaprogramming.html</link>
      <guid>https://soap.coffee/~lthms/posts/LtacMetaprogramming.html</guid>
      <pubDate>August 28, 2020</pubDate>
      <description>
        
        &lt;h1&gt;Ltac is an Imperative Metaprogramming Language&lt;/h1&gt;&lt;div id=&quot;tags-list&quot;&gt;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coq.html&quot; class=&quot;tag hover-sky&quot; marked=&quot;&quot;&gt;coq&lt;/a&gt; &lt;/div&gt;
&lt;p&gt;Coq is often depicted as an &lt;em&gt;interactive&lt;/em&gt; proof assistant, thanks to its
proof environment. Inside the proof environment, Coq presents the user a
goal, and said user solves said goal by means of tactics which describes a
logical reasoning. For instance, to reason by induction, one can use the
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt;&lt;/code&gt; tactic, while a simple case analysis can rely on the
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt;&lt;/code&gt; or &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;case_eq&lt;/span&gt;&lt;/code&gt; tactics, etc.  It is not uncommon for new
Coq users to be introduced to Ltac, the Coq default tactic language, using this
proof-centric approach. This is not surprising, since writing proofs remains
the main use case for Ltac. In practice, though, this discourse remains an
abstraction which hides away what actually happens under the hood when Coq
executes a proof script.&lt;/p&gt;
&lt;p&gt;To really understand what Ltac is about, we need to recall ourselves that
Coq kernel is mostly a type checker. A theorem statement is expressed as a
“type” (which lives in a dedicated sort called &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt;&lt;/code&gt;), and a proof of
this theorem is a term of this type, just like the term &lt;code class=&quot;hljs language-coq&quot;&gt;S (S O)&lt;/code&gt; (&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;2&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)
is of type &lt;code class=&quot;hljs language-coq&quot;&gt;nat&lt;/code&gt;.  Proving a theorem in Coq requires to construct a term
of the type encoding said theorem, and Ltac allows for incrementally
constructing this term, one step at a time.&lt;/p&gt;
&lt;p&gt;Ltac generates terms, therefore it is a metaprogramming language. It does it
incrementally, by using primitives to modifying an implicit state, therefore
it is an imperative language. Henceforth, it is an imperative
metaprogramming language.&lt;/p&gt;
&lt;p&gt;To summarize, a goal presented by Coq inside the environment proof is a hole
within the term being constructed. It is presented to users as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A list of “hypotheses,” which are nothing more than the variables
in the scope of the hole&lt;/li&gt;
&lt;li&gt;A type, which is the type of the term to construct to fill the hole&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We illustrate what happens under the hood of Coq executes a simple proof
script. One can use the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Show&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;&lt;/code&gt; vernacular command to exhibit
this.&lt;/p&gt;
&lt;p&gt;We illustrate how Ltac works with the following example.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Theorem&lt;/span&gt; add_n_O : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (n : nat), n + O = n.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;&lt;/code&gt; vernacular command starts the proof environment. Since no
tactic has been used, the term we are trying to construct consists solely in a
hole, while Coq presents us a goal with no hypothesis, and with the exact type
of our theorem, that is &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (n : nat), n + O = n&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A typical Coq course will explain to students the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;intro&lt;/span&gt;&lt;/code&gt; tactic allows for
turning the premise of an implication into an hypothesis within the context.&lt;/p&gt;
&lt;p class=&quot;katex-block&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;C&lt;/mi&gt;&lt;mo&gt;⊢&lt;/mo&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mo&gt;→&lt;/mo&gt;&lt;mi&gt;Q&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;C \vdash P \rightarrow Q
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.07153em;&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;⊢&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;→&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8778em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;Q&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;p class=&quot;katex-block&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;C&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;P&lt;/mi&gt;&lt;mo&gt;⊢&lt;/mo&gt;&lt;mi&gt;Q&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;C,\ P \vdash Q
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.07153em;&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.13889em;&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;⊢&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8778em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;Q&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is a fundamental rule of deductive reasoning, and &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;intro&lt;/span&gt;&lt;/code&gt; encodes it.
It achieves this by refining the current hole into an anonymous function.
When we use&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  &lt;span class=&quot;hljs-built_in&quot;&gt;intro&lt;/span&gt; n.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;it refines the term&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  ?Goal1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;into&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; (n : nat) =&amp;gt; ?Goal2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next step of this proof is to reason about induction on &lt;code class=&quot;hljs&quot;&gt;n&lt;/code&gt;. For &lt;code class=&quot;hljs&quot;&gt;nat&lt;/code&gt;,
it means that to be able to prove&lt;/p&gt;
&lt;p class=&quot;katex-block&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;P&lt;/mi&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\forall n, \mathrm{P}\ n
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;we need to prove that&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;P&lt;/mi&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\mathrm{P}\ 0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;P&lt;/mi&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;→&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;P&lt;/mi&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;S&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\forall n, \mathrm{P}\ n \rightarrow \mathrm{P}\ (S n)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;→&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05764em;&quot;&gt;S&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt;&lt;/code&gt; tactic effectively turns our goal into two subgoals. But
why is that? Because, under the hood, Ltac is refining the current goal using
the &lt;code class=&quot;hljs language-coq&quot;&gt;nat_ind&lt;/code&gt; function automatically generated by Coq when &lt;code class=&quot;hljs language-coq&quot;&gt;nat&lt;/code&gt;
was defined. The type of &lt;code class=&quot;hljs language-coq&quot;&gt;nat_ind&lt;/code&gt; is&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (P : nat -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt;),
    P &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;
    -&amp;gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; n : nat, P n -&amp;gt; P (S n))
    -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; n : nat, P n
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Interestingly enough, &lt;code class=&quot;hljs language-coq&quot;&gt;nat_ind&lt;/code&gt; is not an axiom. It is a regular Coq
function, whose definition is&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; (P : nat -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt;) (f : P &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)
      (f0 : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; n : nat, P n -&amp;gt; P (S n)) =&amp;gt;
  &lt;span class=&quot;hljs-built_in&quot;&gt;fix&lt;/span&gt; F (n : nat) : P n :=
    &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; n &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; n0 &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; (P n0) &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
    | &lt;span class=&quot;hljs-type&quot;&gt;0&lt;/span&gt; =&amp;gt; f
    | &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; n0 =&amp;gt; f0 n0 (F n0)
    &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, after executing&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; n.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The hidden term we are constructing becomes&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; n : nat =&amp;gt;
     nat_ind
       (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; n0 : nat =&amp;gt; n0 + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = n0)
       ?Goal3
       (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; (n0 : nat) (IHn : n0 + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = n0) =&amp;gt; ?Goal4)
       n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And Coq presents us two goals.&lt;/p&gt;
&lt;p&gt;First, we need to prove &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;P&lt;/mi&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\mathrm{P}\ 0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;P&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, &lt;em&gt;i.e.&lt;/em&gt;,
&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;0 + 0 = 0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7278em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. Similarly to Coq presenting a goal when what we are actually doing
is constructing a term, the use of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;=&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.3669em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;+&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (&lt;em&gt;i.e.&lt;/em&gt;, the Coq notations
mechanism) hides much here. We can ask Coq to be more explicit by using the
vernacular command &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Printing&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;All&lt;/span&gt;&lt;/code&gt; to learn that when Coq presents us
a goal of the form &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;, it is actually looking for a term of type
&lt;code class=&quot;hljs language-coq&quot;&gt;@eq nat (Nat.add O O) O&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;Nat.add&lt;/code&gt; is a regular Coq (recursive) function.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  &lt;span class=&quot;hljs-built_in&quot;&gt;fix&lt;/span&gt; add (n m : nat) {struct n} : nat :=
    &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; n &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
    | &lt;span class=&quot;hljs-type&quot;&gt;0&lt;/span&gt; =&amp;gt; m
    | &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; p =&amp;gt; S (add p m)
    &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, &lt;code class=&quot;hljs language-coq&quot;&gt;eq&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; an axiom. It is a regular inductive type, defined
as follows.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; eq (A : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) (x : A) : A -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt; :=
| &lt;span class=&quot;hljs-type&quot;&gt;eq_refl&lt;/span&gt; : eq A x x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Coming back to our current goal, proving &lt;code class=&quot;hljs language-coq&quot;&gt;@eq nat (Nat.add &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;label for=&quot;fn1&quot; class=&quot;sidenote-number margin-toggle&quot;&gt;&lt;/label&gt;&lt;input id=&quot;fn1&quot; type=&quot;checkbox&quot; class=&quot;margin-toggle&quot;&gt;&lt;span class=&quot;note-right sidenote note&quot;&gt;&lt;span class=&quot;footnote-p&quot;&gt;That is, &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;/code&gt; &lt;/span&gt;
&lt;/span&gt;
requires to construct a term of a type whose only constructor is
&lt;code class=&quot;hljs language-coq&quot;&gt;eq_refl&lt;/code&gt;. &lt;code class=&quot;hljs language-coq&quot;&gt;eq_refl&lt;/code&gt; accepts one argument, and encodes the proof
that said argument is equal to itself. In practice, Coq type checker will accept
the term &lt;code class=&quot;hljs language-coq&quot;&gt;@eq_refl &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; x&lt;/code&gt; when it expects a term of type &lt;code class=&quot;hljs language-coq&quot;&gt;@eq &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; x y&lt;/code&gt;
&lt;em&gt;if&lt;/em&gt; it can reduce &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;y&lt;/code&gt; to the same term.&lt;/p&gt;
&lt;p&gt;Is it the case for &lt;code class=&quot;hljs language-coq&quot;&gt;@eq nat (Nat.add &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;? It is, since by definition
of &lt;code class=&quot;hljs language-coq&quot;&gt;Nat.add&lt;/code&gt;, &lt;code class=&quot;hljs language-coq&quot;&gt;Nat.add &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; x&lt;/code&gt; is reduced to &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt;. We can use the
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;&lt;/code&gt; tactic to tell Coq to fill the current hole with
&lt;code class=&quot;hljs language-coq&quot;&gt;eq_refl&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  + &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Suspicious readers may rely on &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Show&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;&lt;/code&gt; to verify this assertion.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; n : nat =&amp;gt;
     nat_ind
       (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; n0 : nat =&amp;gt; n0 + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = n0)
       eq_refl
       (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; (n0 : nat) (IHn : n0 + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = n0) =&amp;gt; ?Goal4)
       n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;?Goal3&lt;/code&gt; has indeed be replaced by &lt;code class=&quot;hljs&quot;&gt;eq_refl&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;One goal remains, as we need to prove that if &lt;code class=&quot;hljs language-coq&quot;&gt;n + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = n&lt;/code&gt;, then &lt;code class=&quot;hljs language-coq&quot;&gt;S n + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = S n&lt;/code&gt;. Coq can reduce &lt;code class=&quot;hljs language-coq&quot;&gt;S n + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;/code&gt; to &lt;code class=&quot;hljs language-coq&quot;&gt;S (n + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)&lt;/code&gt; by definition
of &lt;code class=&quot;hljs language-coq&quot;&gt;Nat.add&lt;/code&gt;, but it cannot reduce &lt;code class=&quot;hljs language-coq&quot;&gt;S n&lt;/code&gt; more than it already is.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  + &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We cannot just use &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;&lt;/code&gt; here (&lt;em&gt;i.e.&lt;/em&gt;, fill the hole with
&lt;code class=&quot;hljs language-coq&quot;&gt;eq_refl&lt;/code&gt;), since &lt;code class=&quot;hljs language-coq&quot;&gt;S (n + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;)&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;S n&lt;/code&gt; cannot be reduced to
the same term.&lt;/p&gt;
&lt;p&gt;However, at this point of the proof, we have the &lt;code class=&quot;hljs language-coq&quot;&gt;IHn&lt;/code&gt; hypothesis (&lt;em&gt;i.e.&lt;/em&gt;, the
&lt;code class=&quot;hljs language-coq&quot;&gt;IHn&lt;/code&gt; argument of the anonymous function whose body we are trying to
construct). The &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt;&lt;/code&gt; tactic allows for substituting in a type an
occurrence of &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; by &lt;code class=&quot;hljs language-coq&quot;&gt;y&lt;/code&gt; as long as we have a proof of &lt;code class=&quot;hljs language-coq&quot;&gt;x = y&lt;/code&gt;. *)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; IHn.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly to &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt;&lt;/code&gt; using a dedicated function, &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt;&lt;/code&gt; refines
the current hole with the &lt;code class=&quot;hljs language-coq&quot;&gt;eq_ind_r&lt;/code&gt; function&lt;label for=&quot;fn2&quot; class=&quot;sidenote-number margin-toggle&quot;&gt;&lt;/label&gt;&lt;input id=&quot;fn2&quot; type=&quot;checkbox&quot; class=&quot;margin-toggle&quot;&gt;&lt;span class=&quot;note-left sidenote note&quot;&gt;&lt;span class=&quot;footnote-p&quot;&gt;Again, not an axiom. &lt;/span&gt;
&lt;/span&gt;. Replacing &lt;code class=&quot;hljs language-coq&quot;&gt;n + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;/code&gt; with &lt;code class=&quot;hljs language-coq&quot;&gt;n&lt;/code&gt; transforms the goal into &lt;code class=&quot;hljs language-coq&quot;&gt;S n = S n&lt;/code&gt;. Here, we
can use &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;&lt;/code&gt; (i.e., &lt;code class=&quot;hljs language-coq&quot;&gt;eq_refl&lt;/code&gt;) to conclude. *)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;    &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After this last tactic, the work is done. There is no more goal to fill inside
the proof term that we have carefully constructed.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; n : nat =&amp;gt;
     nat_ind
       (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; n0 : nat =&amp;gt; n0 + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = n0)
       eq_refl
       (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; (n0 : nat) (IHn : n0 + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = n0) =&amp;gt;
          eq_ind_r (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; n1 : nat =&amp;gt; S n1 = S n0) eq_refl IHn)
       n)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can finally use &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;&lt;/code&gt; or &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;&lt;/code&gt; to tell Coq to type check this
term. That is, Coq does not trust Ltac, but rather type check the term to
verify it is correct. This way, in case Ltac has a bug which makes it
construct an ill-formed type, at the very least Coq can reject it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In conclusion, tactics are used to incrementally refine hole inside a term
until the latter is complete. They do it in a very specific manner, to
encode certain reasoning rules.&lt;/p&gt;
&lt;p&gt;On the other hand, the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt; tactic provides a generic, low-level way
to do the same thing. Knowing how a given tactic works allows for mimicking
its behavior using the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt; tactic.&lt;/p&gt;
&lt;p&gt;If we take the previous theorem as an example, we can prove it using this
alternative proof script.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Theorem&lt;/span&gt; add_n_O&apos; : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (n : nat), n + O = n.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; n =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;).
  &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; (nat_ind (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; n =&amp;gt; n + &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; = n) &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; n).
  + &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; eq_refl.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; m IHm =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;).
    &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; (eq_ind_r (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; n =&amp;gt; S n = S m) &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; IHm).
    &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; eq_refl.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
        
      </description>
    </item>
    
    
    
    <item>
      <title>Mixing Ltac and Gallina for Fun and Profit</title>
      <link>https://soap.coffee/~lthms/posts/MixingLtacAndGallina.html</link>
      <guid>https://soap.coffee/~lthms/posts/MixingLtacAndGallina.html</guid>
      <pubDate>July 26, 2020</pubDate>
      <description>
        
        &lt;h1&gt;Mixing Ltac and Gallina for Fun and Profit&lt;/h1&gt;&lt;div id=&quot;tags-list&quot;&gt;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coq.html&quot; class=&quot;tag hover-periwinkle&quot; marked=&quot;&quot;&gt;coq&lt;/a&gt; &lt;/div&gt;
&lt;p&gt;One of the most misleading introductions to Coq is to say that “Gallina is
for programs, while tactics are for proofs.”  Indeed, in Coq we construct
terms of given types, always. Terms encodes both programs and proofs about
these programs. Gallina is the preferred way to construct programs, and
tactics are the preferred way to construct proofs.&lt;/p&gt;
&lt;p&gt;The key word here is “preferred.” We do not always need to use tactics to
construct a proof term. Conversely, there are some occasions where
constructing a program with tactics become handy. Furthermore, Coq actually
allows for &lt;em&gt;mixing together&lt;/em&gt; Ltac and Gallina.&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&quot;/~lthms/posts/LtacPatternMatching.html&quot; class=&quot;hover-peach&quot; marked=&quot;&quot;&gt;previous article of this series&lt;/a&gt;, we
discuss how Ltac provides two very interesting features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;With &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; goal &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;&lt;/code&gt; it can inspect its context&lt;/li&gt;
&lt;li&gt;With &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; type of &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;&lt;/code&gt; it can pattern matches on types&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It turns out these features are more than handy when it comes to
metaprogramming (that is, the generation of programs by programs).&lt;/p&gt;
&lt;h2&gt;A Tale of Two Worlds, and Some Bridges&lt;/h2&gt;
&lt;p&gt;Constructing terms proofs directly in Gallina often happens when one is
writing dependently typed definition. For instance, we can write a type-safe
&lt;code class=&quot;hljs language-coq&quot;&gt;from_option&lt;/code&gt; function (inspired by &lt;a href=&quot;https://plv.csail.mit.edu/blog/unwrapping-options.html&quot; class=&quot;hover-periwinkle&quot; marked=&quot;&quot;&gt;this very nice
write-up&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#external-link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;) such that
the option to unwrap shall be accompanied by a proof that said option contains
something. This extra argument is used in the &lt;code class=&quot;hljs language-coq&quot;&gt;None&lt;/code&gt; case to derive a
proof of &lt;code class=&quot;hljs language-coq&quot;&gt;False&lt;/code&gt;, from which we can derive
anything.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; is_some {α} (x : option α) : bool :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; Some &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; =&amp;gt; true | &lt;span class=&quot;hljs-type&quot;&gt;None&lt;/span&gt; =&amp;gt; false &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; is_some_None {α} (x : option α)
  : x = None -&amp;gt; is_some x &amp;lt;&amp;gt; true.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;. &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; H. &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; H. &lt;span class=&quot;hljs-built_in&quot;&gt;discriminate&lt;/span&gt;. &lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; from_option {α}
    (x : option α) (some : is_some x = true)
  : α :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; y &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; x = y -&amp;gt; α &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;Some&lt;/span&gt; x =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; =&amp;gt; x
  | &lt;span class=&quot;hljs-type&quot;&gt;None&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; equ =&amp;gt; False_rect α (is_some_None x equ some)
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt; eq_refl.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In &lt;code class=&quot;hljs language-coq&quot;&gt;from_option&lt;/code&gt;, we construct two proofs without using tactics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;False_rect α (is_some_None x equ some)&lt;/code&gt; to exclude the absurd case&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;eq_refl&lt;/code&gt; in conjunction with a dependent pattern matching (if you are
not familiar with this trick: the main idea is to allow Coq to
“remember” that &lt;code class=&quot;hljs language-coq&quot;&gt;x = None&lt;/code&gt; in the second branch)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can use another approach. We can decide to implement &lt;code class=&quot;hljs language-coq&quot;&gt;from_option&lt;/code&gt;
with a proof script.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; from_option&apos; {α}
    (x : option α) (some : is_some x = true)
  : α.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;case_eq&lt;/span&gt; x.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; y &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; y.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; equ.
    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; equ &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; some.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; is_some_None &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; some.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is a third approach we can consider: mixing Gallina terms and tactics.
This is possible thanks to the &lt;code class=&quot;hljs language-coq&quot;&gt;ltac:()&lt;/code&gt; feature.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; from_option&apos;&apos; {α}
    (x : option α) (some : is_some x = true)
  : α :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; y &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; x = y -&amp;gt; α &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;Some&lt;/span&gt; x =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; =&amp;gt; x
  | &lt;span class=&quot;hljs-type&quot;&gt;None&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; equ =&amp;gt; ltac:(&lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; equ &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; some;
                             now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; is_some_None &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; some)
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt; eq_refl.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When Coq encounters &lt;code class=&quot;hljs language-coq&quot;&gt;ltac:()&lt;/code&gt;, it treats it as a hole. It sets up a
corresponding goal, and tries to solve it with the supplied tactic.&lt;/p&gt;
&lt;p&gt;Conversely, there exists ways to construct terms in Gallina when writing a proof
script. Certain tactics take such terms as arguments. Besides, Ltac provides
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;constr&lt;/span&gt;:()&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;uconstr:()&lt;/code&gt; which work similarly to
&lt;code class=&quot;hljs language-coq&quot;&gt;ltac:()&lt;/code&gt;. The difference between &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;constr&lt;/span&gt;:()&lt;/code&gt; and
&lt;code class=&quot;hljs language-coq&quot;&gt;uconstr:()&lt;/code&gt; is that Coq will try to assign a type to the argument of
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;constr&lt;/span&gt;:()&lt;/code&gt;, but will leave the argument of &lt;code class=&quot;hljs language-coq&quot;&gt;uconstr:()&lt;/code&gt; untyped.&lt;/p&gt;
&lt;p&gt;For instance, consider the following tactic definition.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Tactic&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Notation&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;wrap_id&quot;&lt;/span&gt; uconstr(x) :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; f := uconstr:(&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x =&amp;gt; x) &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; (f x).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; the argument of &lt;code class=&quot;hljs language-coq&quot;&gt;wrap_id&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;f&lt;/code&gt; the anonymous identity function
are not typed. It is only when they are composed together as an argument of
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt;&lt;/code&gt; (which expects a typed argument, more precisely of the type of the
goal) that Coq actually tries to type check it.&lt;/p&gt;
&lt;p&gt;As a consequence, &lt;code class=&quot;hljs language-coq&quot;&gt;wrap_id&lt;/code&gt; generates a specialized identity function for
each specific context.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; zero : nat := ltac:(wrap_id &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The generated anonymous identity function is &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x : nat =&amp;gt; x&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; empty_list α : list α := ltac:(wrap_id nil).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The generated anonymous identity function is &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x : list α =&amp;gt; x&lt;/code&gt;.
Besides, we do not need to give more type information about &lt;code class=&quot;hljs language-coq&quot;&gt;nil&lt;/code&gt;. If
&lt;code class=&quot;hljs language-coq&quot;&gt;wrap_id&lt;/code&gt; were to be expecting a typed term, we would have to replace
&lt;code class=&quot;hljs language-coq&quot;&gt;nil&lt;/code&gt; by [(@nil α)].&lt;/p&gt;
&lt;h2&gt;Beware the Automation Elephant in the Room&lt;/h2&gt;
&lt;p&gt;Proofs and computational programs are encoded in Coq as terms, but there is a
fundamental difference between them, and it is highlighted by one of the axioms
provided by the Coq standard library: proof irrelevance.&lt;/p&gt;
&lt;p&gt;Proof irrelevance states that two proofs of the same theorem (i.e., two proof
terms which share the same type) are essentially equivalent, and can be
substituted without threatening the trustworthiness of the system. From a
formal methods point of view, it makes sense. Even if we value “beautiful
proofs,” we mostly want correct proofs.&lt;/p&gt;
&lt;p&gt;The same reasoning does &lt;em&gt;not&lt;/em&gt; apply to computational programs. Two functions of
type &lt;code class=&quot;hljs language-coq&quot;&gt;nat -&amp;gt; nat -&amp;gt; nat&lt;/code&gt; are unlikely to be equivalent.  For instance,
&lt;code class=&quot;hljs language-coq&quot;&gt;add&lt;/code&gt;, &lt;code class=&quot;hljs language-coq&quot;&gt;mul&lt;/code&gt; or &lt;code class=&quot;hljs language-coq&quot;&gt;sub&lt;/code&gt; share the same type, but computes
totally different results.&lt;/p&gt;
&lt;p&gt;Using tactics such as &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;&lt;/code&gt; to generate terms which do not live inside
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt;&lt;/code&gt; is risky, to say the least. For instance,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; add (x y : nat) : nat := ltac:(&lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works, but it is certainly not what you would expect:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;add = &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; y : nat =&amp;gt; y
     : nat -&amp;gt; nat -&amp;gt; nat
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That being said, if we keep that in mind, and assert the correctness of the
generated programs (either by providing a proof, or by extensively testing it),
there is no particular reason not to use Ltac to generate terms when it makes
sense.&lt;/p&gt;
&lt;p&gt;Dependently typed programming can help you here. If we decorate the return type of
a function with the expected properties of the result wrt. the function’s
arguments, we can ensure the function is correct, and conversely prevent tactics
such as &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;&lt;/code&gt; to generate “incorrect” terms. Interested readers may
refer to &lt;a href=&quot;/~lthms/posts/StronglySpecifiedFunctions.html&quot; class=&quot;hover-lavender&quot; marked=&quot;&quot;&gt;the dedicated series on this very
website&lt;/a&gt;.&lt;/p&gt;
        
      </description>
    </item>
    
    
    
    <item>
      <title>Proving Algebraic Datatypes are “Algebraic”</title>
      <link>https://soap.coffee/~lthms/posts/AlgebraicDatatypes.html</link>
      <guid>https://soap.coffee/~lthms/posts/AlgebraicDatatypes.html</guid>
      <pubDate>July 12, 2020</pubDate>
      <description>
        
        &lt;h1&gt;Proving Algebraic Datatypes are “Algebraic”&lt;/h1&gt;&lt;div id=&quot;tags-list&quot;&gt;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coq.html&quot; class=&quot;tag hover-periwinkle&quot; marked=&quot;&quot;&gt;coq&lt;/a&gt; &lt;/div&gt;
&lt;p&gt;Several programming languages allow programmers to define (potentially
recursive) custom types, by composing together existing ones. For instance, in
OCaml, one can define lists as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;list&lt;/span&gt; =
| &lt;span class=&quot;hljs-type&quot;&gt;Cons&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; * &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;list&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;Nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This translates in Haskell as&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-haskell&quot;&gt;&lt;span class=&quot;hljs-class&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;List&lt;/span&gt; a =&lt;/span&gt;
  &lt;span class=&quot;hljs-type&quot;&gt;Cons&lt;/span&gt; a (&lt;span class=&quot;hljs-type&quot;&gt;List&lt;/span&gt; a)
| &lt;span class=&quot;hljs-type&quot;&gt;Nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Rust as&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-rust&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;List&lt;/span&gt;&amp;lt;A&amp;gt; {
  &lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;Cons&lt;/span&gt;(A, &lt;span class=&quot;hljs-type&quot;&gt;Box&lt;/span&gt;&amp;lt;List&amp;lt;a&amp;gt;&amp;gt;),
  Nil,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or in Coq as&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; list a :=
| &lt;span class=&quot;hljs-type&quot;&gt;cons&lt;/span&gt; : a -&amp;gt; list a -&amp;gt; list a
| &lt;span class=&quot;hljs-type&quot;&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And so forth.&lt;/p&gt;
&lt;p&gt;Each language will have its own specific constructions, and the type systems
of OCaml, Haskell, Rust and Coq —to only cite them— are far from being
equivalent. That being said, they often share a common “base formalism,”
usually (and sometimes abusively) referred to as &lt;em&gt;algebraic datatypes&lt;/em&gt;. This
expression is used because under the hood any datatype can be encoded as a
composition of types using two operators: sum (&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;+&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;) and product (&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;*&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∗&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;) for
types.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a + b&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the disjoint union of types &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;b&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. Any term of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
can be injected into &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a + b&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, and the same goes for &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;b&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. Conversely,
a term of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a + b&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; can be projected into either &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; or &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;b&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a * b&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the Cartesian product of types &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;b&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. Any term of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a *
b&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is made of one term of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and one term of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;b&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (think tuples).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For an algebraic datatype, one constructor allows for defining “named
tuples,” that is ad hoc product types. Besides, constructors are mutually
exclusive: you cannot define the same term using two different constructors.
Therefore, a datatype with several constructors is reminiscent of a disjoint
union.  Coming back to the &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;l&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;i&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;s&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\mathrm{list}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;list&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; type, under the syntactic sugar of
algebraic datatypes, we can define it as&lt;/p&gt;
&lt;p class=&quot;katex-block&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;l&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;i&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;s&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;≡&lt;/mo&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;u&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;n&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;i&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;msub&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;l&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;i&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;s&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\mathrm{list}_\alpha \equiv \mathrm{unit} + \alpha * \mathrm{list}_\alpha
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8444em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;list&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;≡&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7512em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;unit&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8444em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;list&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;u&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;n&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;i&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\mathrm{unit}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6679em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;unit&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; models the &lt;code class=&quot;hljs language-coq&quot;&gt;nil&lt;/code&gt; case, and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;msub&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;l&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;i&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;s&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;α * \mathrm{list}_\alpha&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8444em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;list&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
models the &lt;code class=&quot;hljs language-coq&quot;&gt;cons&lt;/code&gt; case.&lt;/p&gt;
&lt;p&gt;The set of types which can be defined in a language together with &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;+&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and
&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;*&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∗&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; form an “algebraic structure” in the mathematical sense, hence the
name. It means the definitions of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;+&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;*&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∗&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; have to satisfy properties
such as commutativity or the existence of neutral elements. In this article,
we will prove some of them in Coq. More precisely,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;+&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is commutative, that is &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\forall (x, y),\ x + y = y + x&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7778em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;+&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is associative, that is &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\forall (x, y, z),\ (x + y) + z = x + (y + z)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;+&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; has a neutral element, that is &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∃&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mi&gt;s&lt;/mi&gt;&lt;/msub&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mi&gt;s&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\exists e_s,\ \forall x,\ x + e_s = x&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∃&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.5806em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;*&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∗&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is commutative, that is &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\forall (x, y),\ x * y = y * x&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6597em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;*&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∗&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is associative, that is &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\forall (x, y, z),\ (x * y) * z = x * (y * z)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;*&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∗&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; has a neutral element, that is &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∃&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;/msub&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\exists e_p,\ \forall x,\ x * e_p = x&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.9805em;vertical-align:-0.2861em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∃&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;p&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.2861em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7167em;vertical-align:-0.2861em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;p&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.2861em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;The distributivity of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;+&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;*&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∗&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, that is &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\forall
(x, y, z),\ x * (y + z) = x * y + x * z&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7778em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;*&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∗&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; has an absorbing element, that is &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∃&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;/msub&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\exists e_a,\ \forall x, \ x * e_a = e_a&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∃&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;∗&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.5806em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.5806em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot;&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the record, the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; (&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;+&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;+&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;) and &lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt; (&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;*&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4653em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∗&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;) types are defined
in Coq as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt; (A B : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
| &lt;span class=&quot;hljs-type&quot;&gt;inl&lt;/span&gt; : A -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt; A B
| &lt;span class=&quot;hljs-type&quot;&gt;inr&lt;/span&gt; : B -&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt; A B

&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; prod (A B : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
| &lt;span class=&quot;hljs-type&quot;&gt;pair&lt;/span&gt; : A -&amp;gt; B -&amp;gt; prod A B
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;An Equivalence for &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Algebraic structures come with &lt;em&gt;equations&lt;/em&gt; expected to be true.  This means
there is an implicit dependency which is —to my opinion— too easily overlooked:
the definition of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;=&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.3669em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. In Coq, &lt;code class=&quot;hljs language-coq&quot;&gt;=&lt;/code&gt; is a built-in relation that states
that two terms are “equal” if they can be reduced to the same “hierarchy” of
constructors. This is too strong in the general case, and in particular for our
study of algebraic structures of &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;&lt;/code&gt;. It is clear that, to Coq’s
opinion, &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\alpha + \beta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is not structurally &lt;em&gt;equal&lt;/em&gt; to &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\beta + \alpha&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, yet
we will have to prove they are “equivalent.”&lt;/p&gt;
&lt;h3&gt;Introducing &lt;code class=&quot;hljs language-coq&quot;&gt;type_equiv&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Since &lt;code class=&quot;hljs language-coq&quot;&gt;=&lt;/code&gt; for &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;&lt;/code&gt; is not suitable for reasoning about algebraic
datatypes, we introduce our own equivalence relation, denoted &lt;code class=&quot;hljs language-coq&quot;&gt;==&lt;/code&gt;.  We
say two types &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\alpha&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\beta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; are equivalent up to an isomorphism
when for any term of type &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\alpha&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, there exists a counterpart term of type
&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\beta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and vice versa. In other words, &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\alpha&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\beta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; are equivalent if
we can exhibit two functions &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; such that:&lt;/p&gt;
&lt;p class=&quot;katex-block&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;:&lt;/mo&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\forall (x : α),\ x = g(f(x))
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;katex-block&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;:&lt;/mo&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\forall (y : β),\ y = f(g(y))
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This translates into the following inductive type.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Reserved&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Notation&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;x == y&quot;&lt;/span&gt; (&lt;span class=&quot;hljs-built_in&quot;&gt;at&lt;/span&gt; level &lt;span class=&quot;hljs-number&quot;&gt;72&lt;/span&gt;).

&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; type_equiv (α β : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : &lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt; :=
| &lt;span class=&quot;hljs-type&quot;&gt;mk_type_equiv&lt;/span&gt; (f : α -&amp;gt; β) (g : β -&amp;gt; α)
                (equ1 : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (x : α), x = g (f x))
                (equ2 : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (y : β), y = f (g y))
  : α == β
&lt;span class=&quot;hljs-keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;x == y&quot;&lt;/span&gt; := (type_equiv x y).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As mentioned earlier, we prove two types are equivalent by exhibiting
two functions, and proving these functions satisfy two properties. We
introduce a &lt;code class=&quot;hljs&quot;&gt;Ltac&lt;/code&gt; notation to that end.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Tactic&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Notation&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;equiv&quot;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;with&quot;&lt;/span&gt; uconstr(f) &lt;span class=&quot;hljs-string&quot;&gt;&quot;and&quot;&lt;/span&gt; uconstr(g)
  := &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; (mk_type_equiv f g).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The tactic &lt;code class=&quot;hljs language-coq&quot;&gt;equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; f and g&lt;/code&gt; will turn a goal of the form &lt;code class=&quot;hljs language-coq&quot;&gt;α == β&lt;/code&gt; into two subgoals to prove &lt;code class=&quot;hljs&quot;&gt;f&lt;/code&gt; and &lt;code class=&quot;hljs&quot;&gt;g&lt;/code&gt; form an isomorphism.&lt;/p&gt;
&lt;h3&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;type_equiv&lt;/code&gt; is an Equivalence&lt;/h3&gt;
&lt;p&gt;We can prove it by demonstrating it is&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Reflexive,&lt;/li&gt;
&lt;li&gt;Symmetric, and&lt;/li&gt;
&lt;li&gt;Transitive.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;type_equiv&lt;/code&gt; is reflexive&lt;/h4&gt;
&lt;p&gt;This proof is straightforward. A type &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\alpha&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is equivalent to itself because:&lt;/p&gt;
&lt;p class=&quot;katex-block&quot;&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∀&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;:&lt;/mo&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mtext&gt;&amp;nbsp;&lt;/mtext&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;d&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;d&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;mo stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\forall (x : α),\ x = id(id(x))
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;∀&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mspace&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.1667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; type_equiv_refl (α : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : α == α.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  now equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (@id α) and (@id α).
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;type_equiv&lt;/code&gt; is symmetric&lt;/h4&gt;
&lt;p&gt;If &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\alpha = \beta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, then we know there exists two functions &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; which
satisfy the expected properties. We can “swap” them to prove that &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\beta ==
\alpha&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; type_equiv_sym {α β} (equ : α == β) : β == α.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; equ &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; [f g equ1 equ2].
  now equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; g and f.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;type_equiv&lt;/code&gt; is transitive&lt;/h4&gt;
&lt;p&gt;If &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\alpha = \beta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, we know there exists two functions &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f_\alpha&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:-0.1076em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.15em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and
&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g_\beta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7167em;vertical-align:-0.2861em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.3361em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.2861em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; which satisfy the expected properties of &lt;code class=&quot;hljs language-coq&quot;&gt;type_equiv&lt;/code&gt;.
Similarly, because &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;γ&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\beta = \gamma&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05556em;&quot;&gt;γ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;,
we know there exists two additional functions &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f_\beta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.9805em;vertical-align:-0.2861em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.3361em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:-0.1076em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.2861em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mi&gt;γ&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g_\gamma&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7167em;vertical-align:-0.2861em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t vlist-t2&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.1514em;&quot;&gt;&lt;span style=&quot;top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mathnormal mtight&quot; style=&quot;margin-right:0.05556em;&quot;&gt;γ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-s&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.2861em;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. We can
compose these functions together to prove &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;γ&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\alpha = \gamma&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05556em;&quot;&gt;γ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;As a reminder, composing two functions &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (denoted by &lt;code class=&quot;hljs language-coq&quot;&gt;f &amp;gt;&amp;gt;&amp;gt; g&lt;/code&gt;
thereafter) consists in using the result of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; as the input of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.625em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Infix&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&amp;gt;&amp;gt;&amp;gt;&quot;&lt;/span&gt; := (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; f g x =&amp;gt; g (f x)) (&lt;span class=&quot;hljs-built_in&quot;&gt;at&lt;/span&gt; level &lt;span class=&quot;hljs-number&quot;&gt;70&lt;/span&gt;).

&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; type_equiv_trans {α β γ} (equ1 : α == β) (equ2 : β == γ)
  : α == γ.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; equ1 &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; [fα gβ equαβ equβα],
           equ2 &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; [fβ gγ equβγ equγβ].
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (fα &amp;gt;&amp;gt;&amp;gt; fβ) and (gγ &amp;gt;&amp;gt;&amp;gt; gβ).
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; x.
    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equβγ.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equαβ.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; x.
    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equβα.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equγβ.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;The Coq standard library introduces the &lt;code class=&quot;hljs language-coq&quot;&gt;Equivalence&lt;/code&gt; type class. We can
provide an instance of this type class for &lt;code class=&quot;hljs language-coq&quot;&gt;type_equiv&lt;/code&gt;, using the three
lemmas we have proven in this section.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;]
&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; type_equiv_Equivalence : Equivalence type_equiv :=
  {}.

&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; x.
    &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; type_equiv_refl.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; x y.
    &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; type_equiv_sym.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; x y z.
    &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; type_equiv_trans.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Examples&lt;/h3&gt;
&lt;h4&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;list&lt;/code&gt;’s canonical form&lt;/h4&gt;
&lt;p&gt;We now come back to our initial example, given in the introduction of this
write-up. We can prove our assertion, that is &lt;code class=&quot;hljs language-coq&quot;&gt;list α == unit + α * list α&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; list_equiv (α : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;)
  : list α == unit + α * list α.

&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
                       | &lt;span class=&quot;hljs-type&quot;&gt;[] =&amp;gt; inl&lt;/span&gt; tt
                       | &lt;span class=&quot;hljs-type&quot;&gt;x&lt;/span&gt; :: rst =&amp;gt; inr (x, rst)
                       &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;)
         and (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
                       | &lt;span class=&quot;hljs-type&quot;&gt;inl&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; =&amp;gt; []
                       | &lt;span class=&quot;hljs-type&quot;&gt;inr&lt;/span&gt; (x, rst) =&amp;gt; x :: rst
                       &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;).
  + now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [| &lt;span class=&quot;hljs-type&quot;&gt;x&lt;/span&gt; rst].
  + now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [[] | &lt;span class=&quot;hljs-type&quot;&gt;[x&lt;/span&gt; rst]].
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;list&lt;/code&gt; is a morphism&lt;/h4&gt;
&lt;p&gt;This means that if &lt;code class=&quot;hljs language-coq&quot;&gt;α == β&lt;/code&gt;, then &lt;code class=&quot;hljs language-coq&quot;&gt;list α == list β&lt;/code&gt;. We prove this
by defining an instance of the &lt;code class=&quot;hljs language-coq&quot;&gt;Proper&lt;/code&gt; type class.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; list_Proper
  : Proper (type_equiv ==&amp;gt; type_equiv) list.

&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  add_morphism_tactic.
  &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; α β [f g equαβ equβα].
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (map f) and (map g).
  all: &lt;span class=&quot;hljs-built_in&quot;&gt;setoid_rewrite&lt;/span&gt; map_map; &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; l.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;replace&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x : α =&amp;gt; g (f x))
       &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (@id α).
    ++ &lt;span class=&quot;hljs-built_in&quot;&gt;symmetry&lt;/span&gt;; &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; map_id.
    ++ &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; functional_extensionality.
       &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; equαβ.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;replace&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x : β =&amp;gt; f (g x))
       &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (@id β).
    ++ &lt;span class=&quot;hljs-built_in&quot;&gt;symmetry&lt;/span&gt;; &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; map_id.
    ++ &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; functional_extensionality.
       &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; equβα.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The use of the &lt;code class=&quot;hljs language-coq&quot;&gt;Proper&lt;/code&gt; type class allows for leveraging hypotheses of
the form &lt;code class=&quot;hljs language-coq&quot;&gt;α == β&lt;/code&gt; with the &lt;code class=&quot;hljs&quot;&gt;rewrite&lt;/code&gt; tactic. I personally consider
providing instances of &lt;code class=&quot;hljs language-coq&quot;&gt;Proper&lt;/code&gt; whenever it is possible to be a good
practice, and would encourage any Coq programmers to do so.&lt;/p&gt;
&lt;h4&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;nat&lt;/code&gt; is a special purpose &lt;code class=&quot;hljs&quot;&gt;list&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Did you notice? Now, using &lt;code class=&quot;hljs language-coq&quot;&gt;type_equiv&lt;/code&gt;, we can prove it!&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; nat_and_list : nat == list unit.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (&lt;span class=&quot;hljs-built_in&quot;&gt;fix&lt;/span&gt; to_list n :=
                &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; n &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
                | &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; m =&amp;gt; tt :: to_list m
                | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; =&amp;gt; []
                &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;)
         and (&lt;span class=&quot;hljs-built_in&quot;&gt;fix&lt;/span&gt; of_list l :=
                &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
                | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; :: rst =&amp;gt; S (of_list rst)
                | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;
                &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;).
  + &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; x; &lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; y; &lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- IHy.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; a.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Non-empty lists&lt;/h4&gt;
&lt;p&gt;We can introduce a variant of &lt;code class=&quot;hljs language-coq&quot;&gt;list&lt;/code&gt; which contains at least one element
by modifying the &lt;code class=&quot;hljs language-coq&quot;&gt;nil&lt;/code&gt; constructor so that it takes one argument instead
of none.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; non_empty_list (α : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) :=
| &lt;span class=&quot;hljs-type&quot;&gt;ne_cons&lt;/span&gt; : α -&amp;gt; non_empty_list α -&amp;gt; non_empty_list α
| &lt;span class=&quot;hljs-type&quot;&gt;ne_singleton&lt;/span&gt; : α -&amp;gt; non_empty_list α.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can demonstrate the relation between &lt;code class=&quot;hljs language-coq&quot;&gt;list&lt;/code&gt; and
&lt;code class=&quot;hljs language-coq&quot;&gt;non_empty_list&lt;/code&gt;, which reveals an alternative implementation of
&lt;code class=&quot;hljs language-coq&quot;&gt;non_empty_list&lt;/code&gt;. More precisely, we can prove that &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (α : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;), non_empty_list α == α * list α&lt;/code&gt;. It is a bit more cumbersome, but not that
much. We first define the conversion functions, then prove they satisfy the
properties expected by &lt;code class=&quot;hljs language-coq&quot;&gt;type_equiv&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Fixpoint&lt;/span&gt; non_empty_list_of_list {α} (x : α) (l : list α)
  : non_empty_list α :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;y&lt;/span&gt; :: rst =&amp;gt; ne_cons x (non_empty_list_of_list y rst)
  | &lt;span class=&quot;hljs-type&quot;&gt;[] =&amp;gt; ne_singleton&lt;/span&gt; x
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

#[local]
&lt;span class=&quot;hljs-keyword&quot;&gt;Fixpoint&lt;/span&gt; list_of_non_empty_list {α} (l : non_empty_list α)
  : list α :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;ne_cons&lt;/span&gt; x rst =&amp;gt; x :: list_of_non_empty_list rst
  | &lt;span class=&quot;hljs-type&quot;&gt;ne_singleton&lt;/span&gt; x =&amp;gt; [x]
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; list_of_non_empty_list {α} (l : non_empty_list α)
  : α * list α :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;ne_singleton&lt;/span&gt; x =&amp;gt; (x, [])
  | &lt;span class=&quot;hljs-type&quot;&gt;ne_cons&lt;/span&gt; x rst =&amp;gt; (x, list_of_non_empty_list rst)
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; ne_list_list_equiv (α : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;)
  : non_empty_list α == α * list α.

&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; list_of_non_empty_list
         and (prod_curry non_empty_list_of_list).
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x rst|&lt;span class=&quot;hljs-type&quot;&gt;x&lt;/span&gt;]; &lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;revert&lt;/span&gt; x.
    &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; rst; &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; x; &lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt;; now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; IHrst.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x rst].
    &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; rst; &lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;change&lt;/span&gt; (non_empty_list_of_list x (α&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; :: rst))
      &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (ne_cons x (non_empty_list_of_list α&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; rst)).
    &lt;span class=&quot;hljs-built_in&quot;&gt;replace&lt;/span&gt; (α&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; :: rst)
      &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (list_of_non_empty_list
              (non_empty_list_of_list α&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; rst)); &lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;revert&lt;/span&gt; α&lt;span class=&quot;hljs-number&quot;&gt;0.&lt;/span&gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; rst; &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; y; [ &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt; | &lt;span class=&quot;hljs-type&quot;&gt;cbn&lt;/span&gt; ].
    now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; IHrst.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;The &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; Operator&lt;/h2&gt;
&lt;h3&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; Is a Morphism&lt;/h3&gt;
&lt;p&gt;To prove this, we compose together the functions whose existence is implied by
&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;mo mathvariant=&quot;normal&quot; lspace=&quot;0em&quot; rspace=&quot;0em&quot;&gt;′&lt;/mo&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\alpha = \alpha&apos;&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.7519em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.7519em;&quot;&gt;&lt;span style=&quot;top:-3.063em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;′&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;β&lt;/mi&gt;&lt;mo mathvariant=&quot;normal&quot; lspace=&quot;0em&quot; rspace=&quot;0em&quot;&gt;′&lt;/mo&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\beta = \beta&apos;&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8889em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.9463em;vertical-align:-0.1944em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.05278em;&quot;&gt;β&lt;/span&gt;&lt;span class=&quot;msupsub&quot;&gt;&lt;span class=&quot;vlist-t&quot;&gt;&lt;span class=&quot;vlist-r&quot;&gt;&lt;span class=&quot;vlist&quot; style=&quot;height:0.7519em;&quot;&gt;&lt;span style=&quot;top:-3.063em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;pstrut&quot; style=&quot;height:2.7em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size6 size3 mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;&lt;span class=&quot;mord mtight&quot;&gt;′&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. To that end, we introduce the
auxiliary function &lt;code class=&quot;hljs language-coq&quot;&gt;lr_map&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; lr_map_sum {α β α&apos; β&apos;} (f : α -&amp;gt; α&apos;) (g : β -&amp;gt; β&apos;)
    (x : α + β)
  : α&apos; + β&apos; :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;inl&lt;/span&gt; x =&amp;gt; inl (f x)
  | &lt;span class=&quot;hljs-type&quot;&gt;inr&lt;/span&gt; y =&amp;gt; inr (g y)
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, we prove &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; is a morphism by defining a &lt;code class=&quot;hljs language-coq&quot;&gt;Proper&lt;/code&gt; instance.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; sum_Proper
  : Proper (type_equiv ==&amp;gt; type_equiv ==&amp;gt; type_equiv) &lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  add_morphism_tactic.
  &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; α α&apos; [fα gα&apos; equαα&apos; equα&apos;α]
         β β&apos; [fβ gβ&apos; equββ&apos; equβ&apos;β].
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (lr_map_sum fα fβ)
         and (lr_map_sum gα&apos; gβ&apos;).
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x|&lt;span class=&quot;hljs-type&quot;&gt;y&lt;/span&gt;]; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt;.
    ++ now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equαα&apos;.
    ++ now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equββ&apos;.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x|&lt;span class=&quot;hljs-type&quot;&gt;y&lt;/span&gt;]; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt;.
    ++ now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equα&apos;α.
    ++ now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equβ&apos;β.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; Is Commutative&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; sum_invert {α β} (x : α + β) : β + α :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;inl&lt;/span&gt; x =&amp;gt; inr x
  | &lt;span class=&quot;hljs-type&quot;&gt;inr&lt;/span&gt; x =&amp;gt; inl x
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; sum_com {α β} : α + β == β + α.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; sum_invert and sum_invert;
    now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x|&lt;span class=&quot;hljs-type&quot;&gt;x&lt;/span&gt;].
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; Is Associative&lt;/h3&gt;
&lt;p&gt;The associativity of &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; is straightforward to prove, and should not
pose a particular challenge to prospective readers&lt;label for=&quot;fn1&quot; class=&quot;sidenote-number margin-toggle&quot;&gt;&lt;/label&gt;&lt;input id=&quot;fn1&quot; type=&quot;checkbox&quot; class=&quot;margin-toggle&quot;&gt;&lt;span class=&quot;note-right sidenote note&quot;&gt;&lt;span class=&quot;footnote-p&quot;&gt;If we assume that this article is well written, that is. &lt;/span&gt;
&lt;/span&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; sum_assoc {α β γ} : α + β + γ == α + (β + γ).
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x =&amp;gt;
                &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
                | &lt;span class=&quot;hljs-type&quot;&gt;inl&lt;/span&gt; (inl x) =&amp;gt; inl x
                | &lt;span class=&quot;hljs-type&quot;&gt;inl&lt;/span&gt; (inr x) =&amp;gt; inr (inl x)
                | &lt;span class=&quot;hljs-type&quot;&gt;inr&lt;/span&gt; x =&amp;gt; inr (inr x)
                &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;)
         and (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x =&amp;gt;
                &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
                | &lt;span class=&quot;hljs-type&quot;&gt;inl&lt;/span&gt; x =&amp;gt; inl (inl x)
                | &lt;span class=&quot;hljs-type&quot;&gt;inr&lt;/span&gt; (inl x) =&amp;gt; inl (inr x)
                | &lt;span class=&quot;hljs-type&quot;&gt;inr&lt;/span&gt; (inr x) =&amp;gt; inr x
                &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;).
  + now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [[x|&lt;span class=&quot;hljs-type&quot;&gt;x&lt;/span&gt;]|&lt;span class=&quot;hljs-type&quot;&gt;x&lt;/span&gt;].
  + now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x|&lt;span class=&quot;hljs-type&quot;&gt;[x&lt;/span&gt;|&lt;span class=&quot;hljs-type&quot;&gt;x&lt;/span&gt;]].
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; Has A Neutral Element&lt;/h3&gt;
&lt;p&gt;We need to find a type &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;e&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;e&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; such that &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\alpha + e = \alpha&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; for any type
&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;α&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\alpha&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot; style=&quot;margin-right:0.0037em;&quot;&gt;α&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (similarly to &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x + 0 = x&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6667em;vertical-align:-0.0833em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2222em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mspace&quot; style=&quot;margin-right:0.2778em;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; for any natural number &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.4306em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathnormal&quot;&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;).&lt;/p&gt;
&lt;p&gt;Any empty type (that is, a type with no term such as &lt;code class=&quot;hljs language-coq&quot;&gt;False&lt;/code&gt;) can act as
the natural element of &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;&lt;/code&gt;. As a reminder, empty types in Coq are
defined with the following syntax&lt;label for=&quot;fn2&quot; class=&quot;sidenote-number margin-toggle&quot;&gt;&lt;/label&gt;&lt;input id=&quot;fn2&quot; type=&quot;checkbox&quot; class=&quot;margin-toggle&quot;&gt;&lt;span class=&quot;note-left sidenote note&quot;&gt;&lt;span class=&quot;footnote-p&quot;&gt;Note that &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; empty.&lt;/code&gt; is erroneous.&lt;/span&gt;
&lt;span class=&quot;footnote-p&quot;&gt;When the &lt;code class=&quot;hljs language-coq&quot;&gt;:=&lt;/code&gt; is omitted, Coq defines an inductive type with one
constructor, making such a type equivalent to &lt;code class=&quot;hljs language-coq&quot;&gt;unit&lt;/code&gt;, not
&lt;code class=&quot;hljs language-coq&quot;&gt;False&lt;/code&gt;. &lt;/span&gt;
&lt;/span&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; empty := .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From a high-level perspective, &lt;code class=&quot;hljs language-coq&quot;&gt;empty&lt;/code&gt; being the neutral element of
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; makes sense. Because we cannot construct a term of type &lt;code class=&quot;hljs language-coq&quot;&gt;empty&lt;/code&gt;,
then &lt;code class=&quot;hljs language-coq&quot;&gt;α + empty&lt;/code&gt; contains exactly the same numbers of terms as &lt;code class=&quot;hljs language-coq&quot;&gt;α&lt;/code&gt;.
This is the intuition. Now, how can we convince Coq that our intuition is
correct? Just like before, by providing two functions of types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;α -&amp;gt; α + empty&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;α + empty -&amp;gt; α&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first function is &lt;code class=&quot;hljs language-coq&quot;&gt;inl&lt;/code&gt;, that is one of the constructors of
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The second function is trickier to write in Coq, because it comes down to
writing a function of type is &lt;code class=&quot;hljs language-coq&quot;&gt;empty -&amp;gt; α&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; from_empty {α} : empty -&amp;gt; α :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is the exact same trick that allows Coq to encode proofs by
contradiction.&lt;/p&gt;
&lt;p&gt;If we combine &lt;code class=&quot;hljs language-coq&quot;&gt;from_empty&lt;/code&gt; with the generic function&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; unwrap_left_or {α β}
    (f : β -&amp;gt; α) (x : α + β)
  : α :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;inl&lt;/span&gt; x =&amp;gt; x
  | &lt;span class=&quot;hljs-type&quot;&gt;inr&lt;/span&gt; x =&amp;gt; f x
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, we have everything to prove that &lt;code class=&quot;hljs language-coq&quot;&gt;α == α + empty&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; sum_neutral (α : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : α == α + empty.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; inl and (unwrap_left_or from_empty);
    &lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;.
  now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x|&lt;span class=&quot;hljs-type&quot;&gt;x&lt;/span&gt;].
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;The &lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt; Operator&lt;/h2&gt;
&lt;p&gt;This is very similar to what we have just proven for &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt;, so expect
less text for this section.&lt;/p&gt;
&lt;h3&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt; Is A Morphism&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; lr_map_prod {α α&apos; β β&apos;}
    (f : α -&amp;gt; α&apos;) (g : β -&amp;gt; β&apos;)
  : α * β -&amp;gt; α&apos; * β&apos; :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (x, y) =&amp;gt; (f x, g y) &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; prod_Proper
  : Proper (type_equiv ==&amp;gt; type_equiv ==&amp;gt; type_equiv) prod.

&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  add_morphism_tactic.
  &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; α α&apos; [fα gα&apos; equαα&apos; equα&apos;α]
         β β&apos; [fβ gβ&apos; equββ&apos; equβ&apos;β].
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (lr_map_prod fα fβ)
         and (lr_map_prod gα&apos; gβ&apos;).
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x y]; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equαα&apos;.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equββ&apos;.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x y]; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equα&apos;α.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- equβ&apos;β.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt; Is Commutative&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; prod_invert {α β} (x : α * β) : β * α :=
  (snd x, fst x).

&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; prod_com {α β} : α * β == β * α.

&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; prod_invert and prod_invert;
    now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x y].
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt; Is Associative&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; prod_assoc {α β γ}
  : α * β * γ == α * (β * γ).

&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x =&amp;gt;
                &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
                | &lt;span class=&quot;hljs-type&quot;&gt;((x&lt;/span&gt;, y), z) =&amp;gt; (x, (y, z))
                &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;)
         and (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x =&amp;gt;
                &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
                | &lt;span class=&quot;hljs-type&quot;&gt;(x&lt;/span&gt;, (y, z)) =&amp;gt; ((x, y), z)
                &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;).
  + now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [[x y] z].
  + now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x [y z]].
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt; Has A Neutral Element&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; prod_neutral (α : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : α * unit == α.

&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; fst and ((flip pair) tt).
  + now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x []].
  + now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt; Has An Absorbing Element *)&lt;/h3&gt;
&lt;p&gt;And this absorbing element is &lt;code class=&quot;hljs language-coq&quot;&gt;empty&lt;/code&gt;, just like the absorbing element of
the multiplication of natural numbers is &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot;&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;base&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.6444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (that is, the neutral element of
the addition).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; prod_absord (α : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : α * empty == empty.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (snd &amp;gt;&amp;gt;&amp;gt; from_empty)
         and (from_empty).
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [&lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; []].
  + &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [].
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt; And &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; Distributivity&lt;/h2&gt;
&lt;p&gt;Finally, we can prove the distributivity property of &lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt; and
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; using a similar approach to prove the associativity of &lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt;
and &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; prod_sum_distr (α β γ : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;)
  : α * (β + γ) == α * β + α * γ.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  equiv &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
                       | &lt;span class=&quot;hljs-type&quot;&gt;(x&lt;/span&gt;, inr y) =&amp;gt; inr (x, y)
                       | &lt;span class=&quot;hljs-type&quot;&gt;(x&lt;/span&gt;, inl y) =&amp;gt; inl (x, y)
                       &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;)
         and (&lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; x =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
                       | &lt;span class=&quot;hljs-type&quot;&gt;inr&lt;/span&gt; (x, y) =&amp;gt; (x, inr y)
                       | &lt;span class=&quot;hljs-type&quot;&gt;inl&lt;/span&gt; (x, y) =&amp;gt; (x, inl y)
                       &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;).
  + now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [x [y | &lt;span class=&quot;hljs-type&quot;&gt;y&lt;/span&gt;]].
  + now &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [[x y] | &lt;span class=&quot;hljs-type&quot;&gt;[x&lt;/span&gt; y]].
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Bonus: Algebraic Datatypes and Metaprogramming&lt;/h2&gt;
&lt;p&gt;Algebraic datatypes are very suitable for generating functions, as demonstrated
by the automatic deriving of typeclass in Haskell or trait in Rust. Because a
datatype can be expressed in terms of &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt;, you just
have to know how to deal with these two constructions to start metaprogramming.&lt;/p&gt;
&lt;p&gt;We can take the example of the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;fold&lt;/span&gt;&lt;/code&gt; functions. A &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;fold&lt;/span&gt;&lt;/code&gt; function
is a function which takes a container as its argument, and iterates over the
values of that container in order to compute a result.&lt;/p&gt;
&lt;p&gt;We introduce &lt;code class=&quot;hljs language-coq&quot;&gt;fold_type INPUT CANON_FORM OUTPUT&lt;/code&gt;, a tactic to compute the
type of the fold function of the type &lt;code class=&quot;hljs&quot;&gt;INPUT&lt;/code&gt;, whose “canonical form” (in terms
of &lt;code class=&quot;hljs language-coq&quot;&gt;prod&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sum&lt;/span&gt;&lt;/code&gt;) is &lt;code class=&quot;hljs&quot;&gt;CANON_FORM&lt;/code&gt; and whose result type is
&lt;code class=&quot;hljs&quot;&gt;OUTPUT&lt;/code&gt;. Interested readers have to be familiar with &lt;code class=&quot;hljs&quot;&gt;Ltac&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Ltac&lt;/span&gt; fold_args b a r :=
  lazymatch a &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;unit&lt;/span&gt; =&amp;gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; r
  | &lt;span class=&quot;hljs-type&quot;&gt;b&lt;/span&gt; =&amp;gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; (r -&amp;gt; r)
  | &lt;span class=&quot;hljs-type&quot;&gt;(?c&lt;/span&gt; + ?d)%type =&amp;gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; (ltac:(fold_args b c r) * ltac:(fold_args b d r))%type
  | &lt;span class=&quot;hljs-type&quot;&gt;(b&lt;/span&gt; * ?c)%type =&amp;gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; (r -&amp;gt; ltac:(fold_args b c r))
  | &lt;span class=&quot;hljs-type&quot;&gt;(?c&lt;/span&gt; * ?d)%type =&amp;gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; (c -&amp;gt; ltac:(fold_args b d r))
  | &lt;span class=&quot;hljs-type&quot;&gt;?a&lt;/span&gt; =&amp;gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; (a -&amp;gt; r)
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Ltac&lt;/span&gt; currying a :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; a &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;?a&lt;/span&gt; * ?b -&amp;gt; ?c =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; (a -&amp;gt; ltac:(currying (b -&amp;gt; c)))
  | &lt;span class=&quot;hljs-type&quot;&gt;?a&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; a
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Ltac&lt;/span&gt; fold_type b a r :=
  &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; (ltac:(currying (ltac:(fold_args b a r) -&amp;gt; b -&amp;gt; r))).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We use it to compute the type of a &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;fold&lt;/span&gt;&lt;/code&gt; function for &lt;code class=&quot;hljs language-coq&quot;&gt;list&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; fold_list_type (α β : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
  ltac:(fold_type (list α) (unit + α * list α)%type β).
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;fold_list_type =
  &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; α β : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; =&amp;gt; β -&amp;gt; (α -&amp;gt; β -&amp;gt; β) -&amp;gt; list α -&amp;gt; β
     : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is exactly what you could have expected (as match the type of
&lt;code class=&quot;hljs language-coq&quot;&gt;fold_right&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Generating the body of the function is possible in theory, but probably not in
&lt;code class=&quot;hljs&quot;&gt;Ltac&lt;/code&gt; without modifying a bit &lt;code class=&quot;hljs language-coq&quot;&gt;type_equiv&lt;/code&gt;. This could be a nice
use case for &lt;a href=&quot;https://github.com/MetaCoq/metacoq&quot; class=&quot;hover-mint&quot; marked=&quot;&quot;&gt;MetaCoq&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt; though.&lt;/p&gt;
        
      </description>
    </item>
    
    
    
    <item>
      <title>A Study of Clight and its Semantics</title>
      <link>https://soap.coffee/~lthms/posts/ClightIntroduction.html</link>
      <guid>https://soap.coffee/~lthms/posts/ClightIntroduction.html</guid>
      <pubDate>March 20, 2020</pubDate>
      <description>
        
        &lt;h1&gt;A Study of Clight and its Semantics&lt;/h1&gt;&lt;div id=&quot;tags-list&quot;&gt;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coq.html&quot; class=&quot;tag hover-periwinkle&quot; marked=&quot;&quot;&gt;coq&lt;/a&gt; &lt;/div&gt;
&lt;p&gt;CompCert is a certified C compiler which comes with a proof of semantics
preservation. What this means is the following: the semantics of the C code you
write is preserved by CompCert compilation passes up to the generated machine
code.&lt;/p&gt;
&lt;p&gt;I had been interested in CompCert for quite some times, and ultimately
challenged myself to study Clight and its semantics. This write-up is the
result of this challenge, written as I was progressing.&lt;/p&gt;
&lt;h2&gt;Installing CompCert&lt;/h2&gt;
&lt;p&gt;CompCert has been added to &lt;code class=&quot;hljs&quot;&gt;opam&lt;/code&gt;, and as a consequence can be very easily
used as a library for other Coq developments. A typical use case is for a
project to produce Clight (the high-level AST of CompCert), and to benefit
from CompCert proofs after that.&lt;/p&gt;
&lt;p&gt;Installing CompCert is as easy as&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-bash&quot;&gt;opam install coq-compcert
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;More precisely, this article uses &lt;code class=&quot;hljs&quot;&gt;coq-compcert.3.8&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once &lt;code class=&quot;hljs&quot;&gt;opam&lt;/code&gt; terminates, the &lt;code class=&quot;hljs&quot;&gt;compcert&lt;/code&gt; namespace becomes available. In
addition, several binaries are now available if you have correctly set your
&lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&quot;hljs-variable&quot;&gt;$PATH&lt;/span&gt;&lt;/code&gt; environment variable. For instance, &lt;code class=&quot;hljs&quot;&gt;clightgen&lt;/code&gt; takes a C file
as an argument, and generates a Coq file which contains the Clight generated by
CompCert.&lt;/p&gt;
&lt;h2&gt;Problem Statement&lt;/h2&gt;
&lt;p&gt;Our goal for this first write-up is to prove that the C function&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-c&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;hljs-params&quot;&gt;(&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; x, &lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; y)&lt;/span&gt; {
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; x + y;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;returns the expected result, that is &lt;code class=&quot;hljs language-c&quot;&gt;x + y&lt;/code&gt;. The &lt;code class=&quot;hljs&quot;&gt;clightgen&lt;/code&gt; tool
generates (among other things) the following AST&lt;label for=&quot;fn1&quot; class=&quot;sidenote-number margin-toggle&quot;&gt;&lt;/label&gt;&lt;input id=&quot;fn1&quot; type=&quot;checkbox&quot; class=&quot;margin-toggle&quot;&gt;&lt;span class=&quot;note-right sidenote note&quot;&gt;&lt;span class=&quot;footnote-p&quot;&gt;It has been modified in order to improve its readability. &lt;/span&gt;
&lt;/span&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; compcert &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Clight Ctypes Clightdefs AST
                             Coqlib Cop.

&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; _x : &lt;span class=&quot;hljs-keyword&quot;&gt;ident&lt;/span&gt; := &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;%positive.
&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; _y : &lt;span class=&quot;hljs-keyword&quot;&gt;ident&lt;/span&gt; := &lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;%positive.

&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; f_add : function :=
  {| &lt;span class=&quot;hljs-type&quot;&gt;fn_return&lt;/span&gt; := tint
   ; fn_callconv := cc_default
   ; fn_params := [(_x, tint); (_y, tint)]
   ; fn_vars := []
   ; fn_temps := []
   ; fn_body := Sreturn
                  (Some (Ebinop Oadd
                                (Etempvar _x tint)
                                (Etempvar _y tint)
                                tint))
  |&lt;span class=&quot;hljs-type&quot;&gt;}.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fields of the &lt;code class=&quot;hljs language-coq&quot;&gt;function&lt;/code&gt; type are pretty self-explanatory (as it is
often the case in CompCert’s ASTs as far as I can tell for now).&lt;/p&gt;
&lt;p&gt;Identifiers in Clight are (&lt;code class=&quot;hljs language-coq&quot;&gt;positive&lt;/code&gt;) indices.  The &lt;code class=&quot;hljs&quot;&gt;fn_body&lt;/code&gt; field is of
type &lt;code class=&quot;hljs language-coq&quot;&gt;statement&lt;/code&gt;, with the particular constructor &lt;code class=&quot;hljs language-coq&quot;&gt;Sreturn&lt;/code&gt; whose argument
is of type &lt;code class=&quot;hljs language-coq&quot;&gt;option expr&lt;/code&gt;, and &lt;code class=&quot;hljs language-coq&quot;&gt;statement&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;expr&lt;/code&gt; look like the two main
types to study.  The predicates &lt;code class=&quot;hljs language-coq&quot;&gt;step1&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;step2&lt;/code&gt; allow for reasoning
about the execution of a &lt;code class=&quot;hljs language-coq&quot;&gt;function&lt;/code&gt;, step-by-step (hence the name). It
appears that &lt;code class=&quot;hljs&quot;&gt;clightgen&lt;/code&gt; generates Clight terms using the function call
convention encoded by &lt;code class=&quot;hljs language-coq&quot;&gt;step2&lt;/code&gt;.  To reason about a complete execution, it
appears that we can use &lt;code class=&quot;hljs language-coq&quot;&gt;star&lt;/code&gt; (from the &lt;code class=&quot;hljs language-coq&quot;&gt;Smallstep&lt;/code&gt; module) which is
basically a trace of &lt;code class=&quot;hljs language-coq&quot;&gt;step&lt;/code&gt;. These semantics are defined as predicates (that
is, they live in &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt;&lt;/code&gt;). They allow for reasoning about
state transformation, where a state is either&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A function call, with a given list of arguments and a continuation&lt;/li&gt;
&lt;li&gt;A function return, with a result and a continuation&lt;/li&gt;
&lt;li&gt;A &lt;code class=&quot;hljs language-coq&quot;&gt;statement&lt;/code&gt; execution within a &lt;code class=&quot;hljs language-coq&quot;&gt;function&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We import several CompCert modules to manipulate &lt;em&gt;values&lt;/em&gt; (in our case,
bounded integers).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; compcert &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Values Integers.
&lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Int.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Putting everything together, the lemma we want to prove about &lt;code class=&quot;hljs language-coq&quot;&gt;f_add&lt;/code&gt; is
the following.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; f_add_spec (env : genv)
    (t : Events.trace)
    (m m&apos; : Memory.Mem.mem)
    (v : val) (x y z : int)
    (trace : Smallstep.star step2 env
               (Callstate (Ctypes.Internal f_add)
                          [Vint x; Vint y]
                          Kstop
                          m)
               t
               (Returnstate (Vint z) Kstop m&apos;))
  : z = add x y.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Proof Walkthrough&lt;/h2&gt;
&lt;p&gt;We introduce a custom &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;inversion&lt;/span&gt;&lt;/code&gt; tactic which does some clean-up in
addition to just perform the inversion.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Ltac&lt;/span&gt; smart_inv H :=
  &lt;span class=&quot;hljs-built_in&quot;&gt;inversion&lt;/span&gt; H; &lt;span class=&quot;hljs-built_in&quot;&gt;subst&lt;/span&gt;; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; *; &lt;span class=&quot;hljs-built_in&quot;&gt;clear&lt;/span&gt; H.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can now try to prove our lemma.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We first destruct &lt;code class=&quot;hljs language-coq&quot;&gt;trace&lt;/code&gt;, and we rename the generated hypothesis in order
to improve the readability of these notes.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  smart_inv trace.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H into Hstep.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H0 into Hstar.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This generates two hypotheses.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;Hstep : step1
          env
          (Callstate (Ctypes.Internal f_add)
                     [Vint x; Vint y]
                     Kstop
                     m)
          t1
          s2
Hstar : Smallstep.star
          step2
          env
          s2
          t2
          (Returnstate (Vint z) Kstop m&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In other words, to “go” from a &lt;code class=&quot;hljs language-coq&quot;&gt;Callstate&lt;/code&gt; of &lt;code class=&quot;hljs language-coq&quot;&gt;f_add&lt;/code&gt; to a
&lt;code class=&quot;hljs language-coq&quot;&gt;Returnstate&lt;/code&gt;, there is a first step from a &lt;code class=&quot;hljs language-coq&quot;&gt;Callstate&lt;/code&gt; to a state
&lt;code class=&quot;hljs language-coq&quot;&gt;s2&lt;/code&gt;, then a succession of steps to go from &lt;code class=&quot;hljs language-coq&quot;&gt;s2&lt;/code&gt; to a
&lt;code class=&quot;hljs language-coq&quot;&gt;Returnstate&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We consider the single &lt;code class=&quot;hljs language-coq&quot;&gt;step&lt;/code&gt;, in order to determine the actual value of
&lt;code class=&quot;hljs language-coq&quot;&gt;s2&lt;/code&gt; (among other things). To do that, we use &lt;code class=&quot;hljs language-coq&quot;&gt;smart_inv&lt;/code&gt; on
&lt;code class=&quot;hljs language-coq&quot;&gt;Hstep&lt;/code&gt;, and again perform some renaming.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  smart_inv Hstep.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; le into tmp_env.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; e into c_env.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H5 into f_entry.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This produces two effects. First, a new hypothesis is added to the context.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;f_entry : function_entry1
            env
            f_add
            [Vint x; Vint y]
            m
            c_env
            tmp_env
            m1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, the &lt;code class=&quot;hljs language-coq&quot;&gt;Hstar&lt;/code&gt; hypothesis has been updated, because we now have a more
precise value of &lt;code class=&quot;hljs language-coq&quot;&gt;s2&lt;/code&gt;. More precisely, &lt;code class=&quot;hljs language-coq&quot;&gt;s2&lt;/code&gt; has become&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;State
  f_add
  (Sreturn
    (Some (Ebinop Oadd
                  (Etempvar _x tint)
                  (Etempvar _y tint)
                  tint)))
  Kstop
  c_env
  tmp_env
  m1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using the same approach as before, we can uncover the next step.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  smart_inv Hstar.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H into Hstep.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H0 into Hstar.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The resulting hypotheses are&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;Hstep : step2 env
          (State
             f_add
             (Sreturn
               (Some
                 (Ebinop Oadd
                 (Etempvar _x tint)
                 (Etempvar _y tint)
                 tint)))
             Kstop c_env tmp_env m1) t1 s2
Hstar : Smallstep.star
          step2
          env
          s2
          t0
          (Returnstate (Vint z) Kstop m&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An inversion of &lt;code class=&quot;hljs language-coq&quot;&gt;Hstep&lt;/code&gt; can be used to learn more about its resulting
state… So let’s do just that.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  smart_inv Hstep.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H7 into ev.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; v0 into res.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H8 into res_equ.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H9 into mem_equ.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The generated hypotheses have become&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;res : val
ev : eval_expr env c_env tmp_env m1
       (Ebinop Oadd
               (Etempvar _x tint)
               (Etempvar _y tint)
               tint)
       res
res_equ : sem_cast res tint tint m1 = Some v&apos;
mem_equ : Memory.Mem.free_list m1
                               (blocks_of_env env c_env)
            = Some m&apos;0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Our understanding of these hypotheses is the following&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The expression &lt;code class=&quot;hljs language-coq&quot;&gt;_x + _y&lt;/code&gt; is evaluated using the &lt;code class=&quot;hljs language-coq&quot;&gt;c_env&lt;/code&gt;
environment (and we know thanks to &lt;code class=&quot;hljs language-coq&quot;&gt;binding&lt;/code&gt; the value of &lt;code class=&quot;hljs language-coq&quot;&gt;_x&lt;/code&gt;
and &lt;code class=&quot;hljs language-coq&quot;&gt;_y&lt;/code&gt;), and its result is stored in &lt;code class=&quot;hljs language-coq&quot;&gt;res&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;res&lt;/code&gt; is cast into a &lt;code class=&quot;hljs language-coq&quot;&gt;tint&lt;/code&gt; value, and acts as the result of
&lt;code class=&quot;hljs language-coq&quot;&gt;f_add&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code class=&quot;hljs language-coq&quot;&gt;Hstar&lt;/code&gt; hypothesis is now interesting&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;Hstar : Smallstep.star
          step2 env
          (Returnstate v&apos; Kstop m&apos;0) t0
          (Returnstate (Vint z) Kstop m&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is clear that we are at the end of the execution of &lt;code class=&quot;hljs language-coq&quot;&gt;f_add&lt;/code&gt; (even if
Coq generates two subgoals, the second one is not relevant and easy to
discard).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  smart_inv Hstar; [| &lt;span class=&quot;hljs-type&quot;&gt;smart_inv&lt;/span&gt; H ].
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are making good progress here, and we can focus our attention on the &lt;code class=&quot;hljs language-coq&quot;&gt;ev&lt;/code&gt;
hypothesis, which concerns the evaluation of the &lt;code class=&quot;hljs language-coq&quot;&gt;_x + _y&lt;/code&gt; expression. We can
simplify it a bit further.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  smart_inv ev; [| &lt;span class=&quot;hljs-type&quot;&gt;smart_inv&lt;/span&gt; H].
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H4 into fetch_x.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H5 into fetch_y.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H6 into add_op.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In a short-term, the hypotheses &lt;code class=&quot;hljs language-coq&quot;&gt;fetch_x&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;fetch_y&lt;/code&gt; are the
most important.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;fetch_x : eval_expr env c_env tmp_env m1 (Etempvar _x tint) v1
fetch_y : eval_expr env c_env tmp_env m1 (Etempvar _y tint) v2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The current challenge we face is to prove that we know their value.  At this
point, we can have a look at &lt;code class=&quot;hljs language-coq&quot;&gt;f_entry&lt;/code&gt;. This is starting to look
familiar: &lt;code class=&quot;hljs language-coq&quot;&gt;smart_inv&lt;/code&gt;, then renaming, etc.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  smart_inv f_entry.
  &lt;span class=&quot;hljs-built_in&quot;&gt;clear&lt;/span&gt; H.
  &lt;span class=&quot;hljs-built_in&quot;&gt;clear&lt;/span&gt; H0.
  &lt;span class=&quot;hljs-built_in&quot;&gt;clear&lt;/span&gt; H1.
  smart_inv H3; &lt;span class=&quot;hljs-built_in&quot;&gt;subst&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rename&lt;/span&gt; H2 into allocs.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We are almost done. Let’s simplify as much as possible &lt;code class=&quot;hljs language-coq&quot;&gt;fetch_x&lt;/code&gt; and
&lt;code class=&quot;hljs language-coq&quot;&gt;fetch_y&lt;/code&gt;. Each time, the &lt;code class=&quot;hljs language-coq&quot;&gt;smart_inv&lt;/code&gt; tactic generates two subgoals,
but only the first one is relevant. The second one is not, and can be
discarded.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  smart_inv fetch_x; [| &lt;span class=&quot;hljs-type&quot;&gt;inversion&lt;/span&gt; H].
  smart_inv H2.
  smart_inv fetch_y; [| &lt;span class=&quot;hljs-type&quot;&gt;inversion&lt;/span&gt; H].
  smart_inv H2.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We now know the values of the operands of &lt;code class=&quot;hljs language-coq&quot;&gt;add&lt;/code&gt;. The two relevant
hypotheses that we need to consider next are &lt;code class=&quot;hljs language-coq&quot;&gt;add_op&lt;/code&gt; and
&lt;code class=&quot;hljs language-coq&quot;&gt;res_equ&lt;/code&gt;. They are easy to read.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;add_op : sem_binarith
           (fun (_ : signedness) (n1 n2 : Integers.int)
              =&amp;gt; Some (Vint (add n1 n2)))
           (fun (_ : signedness) (n1 n2 : int64)
              =&amp;gt; Some (Vlong (Int64.add n1 n2)))
           (fun n1 n2 : Floats.float
              =&amp;gt; Some (Vfloat (Floats.Float.add n1 n2)))
           (fun n1 n2 : Floats.float32
              =&amp;gt; Some (Vsingle (Floats.Float32.add n1 n2)))
           v1 tint v2 tint m1 = Some res
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;add_op&lt;/code&gt; is the addition of &lt;code class=&quot;hljs language-coq&quot;&gt;Vint x&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;Vint y&lt;/code&gt;, and its
result is &lt;code class=&quot;hljs language-coq&quot;&gt;res&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;res_equ : sem_cast res tint tint m1 = Some (Vint z)
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;res_equ&lt;/code&gt; is the equation which says that the result of &lt;code class=&quot;hljs language-coq&quot;&gt;f_add&lt;/code&gt; is &lt;code class=&quot;hljs language-coq&quot;&gt;res&lt;/code&gt;,
after it has been cast as a &lt;code class=&quot;hljs language-coq&quot;&gt;tint&lt;/code&gt; value.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can simplify &lt;code class=&quot;hljs language-coq&quot;&gt;add_op&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;res_equ&lt;/code&gt;, and this allows us to
conclude.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  smart_inv add_op.
  smart_inv res_equ.
  &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The definitions of Clight are straightforward, and the &lt;a href=&quot;http://compcert.inria.fr/doc/&quot; class=&quot;hover-peach&quot; marked=&quot;&quot;&gt;CompCert
documentation&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#external-link&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt; is very pleasant to
read. Understanding Clight and its semantics can be very interesting if you
are working on a language that you want to translate into machine code.
However, proving some functional properties of a given C snippet using only CompCert
can quickly become cumbersome. From this perspective, the
&lt;a href=&quot;https://github.com/PrincetonUniversity/VST&quot; class=&quot;hover-mint&quot; marked=&quot;&quot;&gt;VST&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt; project is very interesting,
as its main purpose is to provide tools to reason about Clight programs more
easily.&lt;/p&gt;
        
      </description>
    </item>
    
    
    
    <item>
      <title>Rewriting in Coq</title>
      <link>https://soap.coffee/~lthms/posts/RewritingInCoq.html</link>
      <guid>https://soap.coffee/~lthms/posts/RewritingInCoq.html</guid>
      <pubDate>May 13, 2017</pubDate>
      <description>
        
        &lt;h1&gt;Rewriting in Coq&lt;/h1&gt;&lt;div id=&quot;tags-list&quot;&gt;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coq.html&quot; class=&quot;tag hover-lavender&quot; marked=&quot;&quot;&gt;coq&lt;/a&gt; &lt;/div&gt;
&lt;p&gt;I have to confess something. In the codebase of SpecCert lies a shameful
secret, which takes the form of a set of unnecessary axioms.&lt;/p&gt;
&lt;p&gt;I thought I couldn’t avoid them at first, but it was before I heard about
“generalized rewriting,” setoids and morphisms.  Now, I know the truth, and I
will have to update SpecCert eventually. But, in the meantime, let me try to
explain how it is possible to rewrite a term in a proof using an ad hoc
equivalence relation and, when necessary, a proper morphism.&lt;/p&gt;
&lt;h2&gt;Case Study: Gate System&lt;/h2&gt;
&lt;p&gt;Now, why would anyone want such a thing as “generalized rewriting” when the
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt;&lt;/code&gt; tactic works just fine.&lt;/p&gt;
&lt;p&gt;The thing is: it does not in some cases. To illustrate my statement, we will
consider the following definition of a gate in Coq:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Record&lt;/span&gt; Gate :=
  { open:           bool
  ; lock:           bool
  ; lock_is_close:  lock = true -&amp;gt; open = false
  }.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;According to this definition, a gate can be either open or closed. It can also
be locked, but if it is, it cannot be open at the same time. To express this
constraint, we embed the appropriate proposition inside the Record. By doing so,
we &lt;em&gt;know&lt;/em&gt; for sure that we will never meet an ill-formed &lt;code class=&quot;hljs language-coq&quot;&gt;Gate&lt;/code&gt; instance.
The Coq engine will prevent it, because to construct a gate, one will have to
prove the &lt;code class=&quot;hljs language-coq&quot;&gt;lock_is_close&lt;/code&gt; predicate holds.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;hljs language-coq&quot;&gt;program&lt;/code&gt; attribute makes it easy to work with embedded proofs. For
instance, defining the ”open gate” is as easy as:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Coq.&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;.Tactics.

#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; open_gate :=
  {| &lt;span class=&quot;hljs-type&quot;&gt;open&lt;/span&gt; := true
   ; lock := false
   |&lt;span class=&quot;hljs-type&quot;&gt;}.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Under the hood, &lt;code class=&quot;hljs language-coq&quot;&gt;program&lt;/code&gt; proves what needs to be proven, that is the
&lt;code class=&quot;hljs language-coq&quot;&gt;lock_is_close&lt;/code&gt; proposition. Just have a look at its output:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;open_gate has type-checked, generating 1 obligation(s)
Solving obligations automatically...
open_gate_obligation_1 is defined
No more obligations remaining
open_gate is defined
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, using &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt; is a bit like cracking a nut with a
sledgehammer. We can easily do it ourselves using the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt; tactic.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; open_gate&apos;: Gate.
  &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; ({| &lt;span class=&quot;hljs-type&quot;&gt;open&lt;/span&gt; := true
           ; lock := false
          |&lt;span class=&quot;hljs-type&quot;&gt;}).
  intro&lt;/span&gt; Hfalse.
  &lt;span class=&quot;hljs-built_in&quot;&gt;discriminate&lt;/span&gt; Hfalse.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;Gate&lt;/code&gt; Equality&lt;/h2&gt;
&lt;p&gt;What does it mean for two gates to be equal? Intuitively, we know they have to
share the same states (&lt;code class=&quot;hljs language-coq&quot;&gt;open&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;lock&lt;/code&gt; is our case).&lt;/p&gt;
&lt;h3&gt;Leibniz Equality Is Too Strong&lt;/h3&gt;
&lt;p&gt;When you write something like &lt;code class=&quot;hljs language-coq&quot;&gt;a = b&lt;/code&gt; in Coq, the &lt;code class=&quot;hljs language-coq&quot;&gt;=&lt;/code&gt; refers to the
&lt;code class=&quot;hljs language-coq&quot;&gt;eq&lt;/code&gt; function and this function relies on what is called the Leibniz Equality:
&lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;y&lt;/code&gt; are equal iff every property on &lt;code class=&quot;hljs language-coq&quot;&gt;A&lt;/code&gt; which is true
of &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; is also true of &lt;code class=&quot;hljs language-coq&quot;&gt;y&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As for myself, when I first started to write some Coq code, the
Leibniz Equality was not really something I cared about and I tried to
prove something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; open_gates_are_equal (g g&apos;: Gate)
    (equ : open g = true) (equ&apos; : open g&apos; = true)
  : g = g&apos;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Basically, it means that if two doors are open, then they are equal. That made
sense to me, because by definition of &lt;code class=&quot;hljs language-coq&quot;&gt;Gate&lt;/code&gt;, a locked door is closed,
meaning an open door cannot be locked.&lt;/p&gt;
&lt;p&gt;Here is an attempt to prove the &lt;code class=&quot;hljs language-coq&quot;&gt;open_gates_are_equal&lt;/code&gt; lemma.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;assert&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; g, open g = true -&amp;gt; lock g = false). {
    &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; [o l h] equo.
    &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; *.
    &lt;span class=&quot;hljs-built_in&quot;&gt;case_eq&lt;/span&gt; l; &lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; equl.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; (h equl) &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; equo.
  }
  &lt;span class=&quot;hljs-built_in&quot;&gt;assert&lt;/span&gt; (lock g = false) &lt;span class=&quot;hljs-built_in&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; (H &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; equ).
  &lt;span class=&quot;hljs-built_in&quot;&gt;assert&lt;/span&gt; (lock g&apos; = false) &lt;span class=&quot;hljs-built_in&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; (H &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; equ&apos;).
  &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; g; &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; g&apos;; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; *; &lt;span class=&quot;hljs-built_in&quot;&gt;subst&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The term to prove is now:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;{| open := true; lock := false; lock_is_close := lock_is_close0 |} =
{| open := true; lock := false; lock_is_close := lock_is_close1 |}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next tactic I wanted to use &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;&lt;/code&gt;, because I&apos;d basically proven
&lt;code class=&quot;hljs language-coq&quot;&gt;open g = open g&apos;&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;lock g = lock g&apos;&lt;/code&gt;, which meets my definition of equality
at that time.&lt;/p&gt;
&lt;p&gt;Except Coq wouldn’t agree. See how it reacts:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;Unable to unify &quot;{| open := true; lock := false; lock_is_close := lock_is_close1 |}&quot;
  with &quot;{| open := true; lock := false; lock_is_close := lock_is_close0 |}&quot;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It cannot unify the two records. More precisely, it cannot unify
&lt;code class=&quot;hljs language-coq&quot;&gt;lock_is_close1&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;lock_is_close0&lt;/code&gt;. So we abort and try something
else.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Abort&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Ah-Hoc Equivalence Relation&lt;/h3&gt;
&lt;p&gt;This is a familiar pattern. Coq cannot guess what we have in mind. Giving a
formal definition of “our equality” is fortunately straightforward.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; gate_eq
           (g g&apos;: Gate)
  : &lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt; :=
  open g = open g&apos; /\ lock g = lock g&apos;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because “equality” means something very specific in Coq, we won&apos;t say “two
gates are equal” anymore, but “two gates are equivalent.” That is,
&lt;code class=&quot;hljs language-coq&quot;&gt;gate_eq&lt;/code&gt; is an equivalence relation. But “equivalence relation” is also
something very specific. For instance, such relation needs to be symmetric (&lt;code class=&quot;hljs language-coq&quot;&gt;R x y -&amp;gt; R y x&lt;/code&gt;), reflexive (&lt;code class=&quot;hljs language-coq&quot;&gt;R x x&lt;/code&gt;) and transitive (&lt;code class=&quot;hljs language-coq&quot;&gt;R x y -&amp;gt; R y z -&amp;gt; R x z&lt;/code&gt;).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Coq.&lt;span class=&quot;hljs-keyword&quot;&gt;Classes&lt;/span&gt;.Equivalence.

#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; Gate_Equivalence
  : Equivalence gate_eq.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;split&lt;/span&gt;; &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; g g&apos; [Hop Hlo].
  &lt;span class=&quot;hljs-built_in&quot;&gt;symmetry&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; Hop; &lt;span class=&quot;hljs-built_in&quot;&gt;symmetry&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; Hlo.
  &lt;span class=&quot;hljs-built_in&quot;&gt;split&lt;/span&gt;; &lt;span class=&quot;hljs-built_in&quot;&gt;assumption&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; g g&apos; g&apos;&apos; [Hop Hlo] [Hop&apos; Hlo&apos;].
  &lt;span class=&quot;hljs-built_in&quot;&gt;split&lt;/span&gt;.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;transitivity&lt;/span&gt; (open g&apos;); [&lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; Hop|&lt;span class=&quot;hljs-type&quot;&gt;exact&lt;/span&gt; Hop&apos;].
  + &lt;span class=&quot;hljs-built_in&quot;&gt;transitivity&lt;/span&gt; (lock g&apos;); [&lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; Hlo|&lt;span class=&quot;hljs-type&quot;&gt;exact&lt;/span&gt; Hlo&apos;].
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Afterwards, the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;symmetry&lt;/span&gt;&lt;/code&gt;, &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;transitivity&lt;/span&gt;&lt;/code&gt;
tactics also works with &lt;code class=&quot;hljs language-coq&quot;&gt;gate_eq&lt;/code&gt;, in addition to &lt;code class=&quot;hljs language-coq&quot;&gt;eq&lt;/code&gt;. We can try
again to prove the &lt;code class=&quot;hljs language-coq&quot;&gt;open_gate_are_the_same&lt;/code&gt; lemma and it will
work&lt;label for=&quot;fn1&quot; class=&quot;sidenote-number margin-toggle&quot;&gt;&lt;/label&gt;&lt;input id=&quot;fn1&quot; type=&quot;checkbox&quot; class=&quot;margin-toggle&quot;&gt;&lt;span class=&quot;note-right sidenote note&quot;&gt;&lt;span class=&quot;footnote-p&quot;&gt;I know I should have proven an intermediate lemma to avoid code
duplication. Sorry about that, it hurts my eyes too. &lt;/span&gt;
&lt;/span&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; open_gates_are_the_same:
  &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (g g&apos;: Gate),
    open g = true
    -&amp;gt; open g&apos; = true
    -&amp;gt; gate_eq g g&apos;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; g; &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; g&apos;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; H0 H2.
  &lt;span class=&quot;hljs-built_in&quot;&gt;assert&lt;/span&gt; (lock0 = false).
  + &lt;span class=&quot;hljs-built_in&quot;&gt;case_eq&lt;/span&gt; lock0; [ &lt;span class=&quot;hljs-built_in&quot;&gt;intro&lt;/span&gt; H; &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; lock_is_close0 &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; H;
                     &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; H0 &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; H;
                     &lt;span class=&quot;hljs-built_in&quot;&gt;discriminate&lt;/span&gt; H
                   | &lt;span class=&quot;hljs-type&quot;&gt;reflexivity&lt;/span&gt;
                   ].
  + &lt;span class=&quot;hljs-built_in&quot;&gt;assert&lt;/span&gt; (lock1 = false).
    * &lt;span class=&quot;hljs-built_in&quot;&gt;case_eq&lt;/span&gt; lock1; [ &lt;span class=&quot;hljs-built_in&quot;&gt;intro&lt;/span&gt; H&apos;; &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; lock_is_close1 &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; H&apos;;
                       &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; H2 &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; H&apos;;
                       &lt;span class=&quot;hljs-built_in&quot;&gt;discriminate&lt;/span&gt; H&apos;
                     | &lt;span class=&quot;hljs-type&quot;&gt;reflexivity&lt;/span&gt;
                     ].
    * &lt;span class=&quot;hljs-built_in&quot;&gt;subst&lt;/span&gt;.
      &lt;span class=&quot;hljs-built_in&quot;&gt;split&lt;/span&gt;; &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Equivalence Relations and Rewriting&lt;/h2&gt;
&lt;p&gt;So here we are, with our ad hoc definition of gate equivalence. We can use
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;symmetry&lt;/span&gt;&lt;/code&gt;, &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;transitivity&lt;/span&gt;&lt;/code&gt; along with
&lt;code class=&quot;hljs language-coq&quot;&gt;gate_eq&lt;/code&gt; and it works fine because we have told Coq &lt;code class=&quot;hljs language-coq&quot;&gt;gate_eq&lt;/code&gt; is
indeed an equivalence relation for &lt;code class=&quot;hljs language-coq&quot;&gt;Gate&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Can we do better? Can we actually use &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt;&lt;/code&gt; to replace an occurrence
of &lt;code class=&quot;hljs language-coq&quot;&gt;g&lt;/code&gt; by an occurrence of &lt;code class=&quot;hljs language-coq&quot;&gt;g’&lt;/code&gt; as long as we can prove that
&lt;code class=&quot;hljs language-coq&quot;&gt;gate_eq g g’&lt;/code&gt;? The answer is “yes”, but it will not come for free.&lt;/p&gt;
&lt;p&gt;Before moving forward, just consider the following function:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Coq.Bool.Bool.

&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; try_open
        (g: Gate)
  : Gate :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; eqb (lock g) false
  &lt;span class=&quot;hljs-keyword&quot;&gt;then&lt;/span&gt; {| &lt;span class=&quot;hljs-type&quot;&gt;lock&lt;/span&gt; := false
        ; open := true
       |&lt;span class=&quot;hljs-type&quot;&gt;}
  else&lt;/span&gt; g.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It takes a gate as an argument and returns a new gate. If the former is not
locked, the latter is open. Otherwise the argument is returned as is.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; gate_eq_try_open_eq
  : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (g g&apos;: Gate),
    gate_eq g g&apos;
    -&amp;gt; gate_eq (try_open g) (try_open g&apos;).
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; g g&apos; Heq.
&lt;span class=&quot;hljs-keyword&quot;&gt;Abort&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What we could have wanted to do is: &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; Heq&lt;/code&gt;. Indeed, &lt;code class=&quot;hljs language-coq&quot;&gt;g&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;g’&lt;/code&gt;
“are the same” (&lt;code class=&quot;hljs language-coq&quot;&gt;gate_eq g g’&lt;/code&gt;), so, &lt;em&gt;of course&lt;/em&gt;, the results of &lt;code class=&quot;hljs language-coq&quot;&gt;try_open g&lt;/code&gt; and
&lt;code class=&quot;hljs language-coq&quot;&gt;try_open g’&lt;/code&gt; have to be the same. Except...&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;Error: Tactic failure: setoid rewrite failed: Unable to satisfy the following constraints:
UNDEFINED EVARS:
 ?X49==[g g&apos; Heq |- relation Gate] (internal placeholder) {?r}
 ?X50==[g g&apos; Heq (do_subrelation:=Morphisms.do_subrelation)
         |- Morphisms.Proper (gate_eq ==&amp;gt; ?X49@{__:=g; __:=g&apos;; __:=Heq}) try_open] (internal placeholder) {?p}
 ?X52==[g g&apos; Heq |- relation Gate] (internal placeholder) {?r0}
 ?X53==[g g&apos; Heq (do_subrelation:=Morphisms.do_subrelation)
         |- Morphisms.Proper (?X49@{__:=g; __:=g&apos;; __:=Heq} ==&amp;gt; ?X52@{__:=g; __:=g&apos;; __:=Heq} ==&amp;gt; Basics.flip Basics.impl) eq]
         (internal placeholder) {?p0}
 ?X54==[g g&apos; Heq |- Morphisms.ProperProxy ?X52@{__:=g; __:=g&apos;; __:=Heq} (try_open g&apos;)] (internal placeholder) {?p1}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What Coq is trying to tell us here —in a very poor manner, I’d say— is actually
pretty simple. It cannot replace &lt;code class=&quot;hljs language-coq&quot;&gt;g&lt;/code&gt; by &lt;code class=&quot;hljs language-coq&quot;&gt;g’&lt;/code&gt; because it does not
know if two equivalent gates actually give the same result when passed as the
argument of &lt;code class=&quot;hljs language-coq&quot;&gt;try_open&lt;/code&gt;. This is actually what we want to prove, so we
cannot use &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt;&lt;/code&gt; just yet, because it needs this result so it can do
its magic. Chicken and egg problem.&lt;/p&gt;
&lt;p&gt;In other words, we are making the same mistake as before: not telling Coq what
it cannot guess by itself.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt;&lt;/code&gt; tactic works out of the box with the Coq equality
(&lt;code class=&quot;hljs language-coq&quot;&gt;eq&lt;/code&gt;, or most likely &lt;code class=&quot;hljs language-coq&quot;&gt;=&lt;/code&gt;) because of the Leibniz Equality:
&lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;y&lt;/code&gt; are equal iff every property on &lt;code class=&quot;hljs language-coq&quot;&gt;A&lt;/code&gt; which is true
of &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; is also true of &lt;code class=&quot;hljs language-coq&quot;&gt;y&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This is a pretty strong property, and one that a lot of equivalence relations do not
have. Want an example? Consider the relation &lt;code class=&quot;hljs language-coq&quot;&gt;R&lt;/code&gt; over &lt;code class=&quot;hljs language-coq&quot;&gt;A&lt;/code&gt; such that
forall &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;y&lt;/code&gt;, &lt;code class=&quot;hljs language-coq&quot;&gt;R x y&lt;/code&gt; holds true. Such a relation is
reflexive, symmetric and reflexive. Yet, there is very little chance that given
a function &lt;code class=&quot;hljs language-coq&quot;&gt;f : A -&amp;gt; B&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;R’&lt;/code&gt; an equivalence relation over
&lt;code class=&quot;hljs language-coq&quot;&gt;B&lt;/code&gt;, &lt;code class=&quot;hljs language-coq&quot;&gt;R x y -&amp;gt; R&apos; (f x) (f y)&lt;/code&gt;. Only if we have this property, we
would know that we could rewrite &lt;code class=&quot;hljs language-coq&quot;&gt;f x&lt;/code&gt; by &lt;code class=&quot;hljs language-coq&quot;&gt;f y&lt;/code&gt;, &lt;em&gt;e.g.&lt;/em&gt;, in &lt;code class=&quot;hljs language-coq&quot;&gt;R&apos; z (f x)&lt;/code&gt;. Indeed, by transitivity of &lt;code class=&quot;hljs language-coq&quot;&gt;R’&lt;/code&gt;, we can deduce &lt;code class=&quot;hljs language-coq&quot;&gt;R&apos; z (f y)&lt;/code&gt; from &lt;code class=&quot;hljs language-coq&quot;&gt;R&apos; z (f x)&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;R (f x) (f y)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If &lt;code class=&quot;hljs language-coq&quot;&gt;R x y -&amp;gt; R&apos; (f x) (f y)&lt;/code&gt;, then &lt;code class=&quot;hljs language-coq&quot;&gt;f&lt;/code&gt; is a morphism because it
preserves an equivalence relation.  In our previous case, &lt;code class=&quot;hljs language-coq&quot;&gt;A&lt;/code&gt; is
&lt;code class=&quot;hljs language-coq&quot;&gt;Gate&lt;/code&gt;, &lt;code class=&quot;hljs language-coq&quot;&gt;R&lt;/code&gt; is &lt;code class=&quot;hljs language-coq&quot;&gt;gate_eq&lt;/code&gt;, &lt;code class=&quot;hljs language-coq&quot;&gt;f&lt;/code&gt; is &lt;code class=&quot;hljs language-coq&quot;&gt;try_open&lt;/code&gt; and
therefore &lt;code class=&quot;hljs language-coq&quot;&gt;B&lt;/code&gt; is &lt;code class=&quot;hljs language-coq&quot;&gt;Gate&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;R’&lt;/code&gt; is &lt;code class=&quot;hljs language-coq&quot;&gt;gate_eq&lt;/code&gt;. To make
Coq aware that &lt;code class=&quot;hljs language-coq&quot;&gt;try_open&lt;/code&gt; is a morphism, we can use the following syntax:
*)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[local]
&lt;span class=&quot;hljs-keyword&quot;&gt;Open&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Scope&lt;/span&gt; signature_scope.

&lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Coq.&lt;span class=&quot;hljs-keyword&quot;&gt;Classes&lt;/span&gt;.Morphisms.

#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Instance&lt;/span&gt; try_open_Proper
  : Proper (gate_eq ==&amp;gt; gate_eq) try_open.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This notation is actually more generic because you can deal with functions that
take more than one argument. Hence, given &lt;code class=&quot;hljs language-coq&quot;&gt;g : A -&amp;gt; B -&amp;gt; C -&amp;gt; D&lt;/code&gt;,
&lt;code class=&quot;hljs language-coq&quot;&gt;R&lt;/code&gt; (respectively &lt;code class=&quot;hljs language-coq&quot;&gt;R’&lt;/code&gt;, &lt;code class=&quot;hljs language-coq&quot;&gt;R’’&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;R’’’&lt;/code&gt;) an equivalent
relation of &lt;code class=&quot;hljs language-coq&quot;&gt;A&lt;/code&gt; (respectively &lt;code class=&quot;hljs language-coq&quot;&gt;B&lt;/code&gt;, &lt;code class=&quot;hljs language-coq&quot;&gt;C&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;D&lt;/code&gt;), we can
prove &lt;code class=&quot;hljs language-coq&quot;&gt;f&lt;/code&gt; is a morphism as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Add&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Parametric&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Morphism&lt;/span&gt;: (g)
    &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt; signature (R) ==&amp;gt; (R&apos;) ==&amp;gt; (R&apos;&apos;) ==&amp;gt; (R&apos;&apos;&apos;)
      &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; &amp;lt;name&amp;gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Back to our &lt;code class=&quot;hljs language-coq&quot;&gt;try_open&lt;/code&gt; morphism. Coq needs you to prove the following
goal:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;1 subgoal, subgoal 1 (ID 50)

  ============================
  forall x y : Gate, gate_eq x y -&amp;gt; gate_eq (try_open x) (try_open y)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is a way to prove that:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; g g&apos; Heq.
  &lt;span class=&quot;hljs-built_in&quot;&gt;assert&lt;/span&gt; (gate_eq g g&apos;) &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; [Hop Hlo] &lt;span class=&quot;hljs-built_in&quot;&gt;by&lt;/span&gt; (&lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; Heq).
  &lt;span class=&quot;hljs-built_in&quot;&gt;unfold&lt;/span&gt; try_open.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- Hlo.
  &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; (bool_dec (lock g) false) &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; [Hlock|&lt;span class=&quot;hljs-type&quot;&gt;Hnlock&lt;/span&gt;]; &lt;span class=&quot;hljs-built_in&quot;&gt;subst&lt;/span&gt;.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; Hlock.
    &lt;span class=&quot;hljs-built_in&quot;&gt;split&lt;/span&gt;; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt;; &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; not_false_is_true &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; Hnlock.
    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; Hnlock.
    &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;exact&lt;/span&gt; Heq.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, back to our &lt;code class=&quot;hljs language-coq&quot;&gt;gate_eq_try_open_eq&lt;/code&gt;, we now can use &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt;&lt;/code&gt;
and &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Coq.Setoids.&lt;span class=&quot;hljs-keyword&quot;&gt;Setoid&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Lemma&lt;/span&gt; gate_eq_try_open_eq
  : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (g g&apos;: Gate),
    gate_eq g g&apos;
    -&amp;gt; gate_eq (try_open g) (try_open g&apos;).
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; g g&apos; Heq.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; Heq.
  &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We did it! We actually rewrite &lt;code class=&quot;hljs language-coq&quot;&gt;g&lt;/code&gt; as &lt;code class=&quot;hljs language-coq&quot;&gt;g’&lt;/code&gt;, even if we weren’t able
to prove &lt;code class=&quot;hljs language-coq&quot;&gt;g = g’&lt;/code&gt;.&lt;/p&gt;
        
      </description>
    </item>
    
    
    
    <item>
      <title>Implementing Strongly-Specified Functions with the Program Framework</title>
      <link>https://soap.coffee/~lthms/posts/StronglySpecifiedFunctionsProgram.html</link>
      <guid>https://soap.coffee/~lthms/posts/StronglySpecifiedFunctionsProgram.html</guid>
      <pubDate>January 1, 2017</pubDate>
      <description>
        
        &lt;h1&gt;Implementing Strongly-Specified Functions with the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt; Framework&lt;/h1&gt;&lt;div id=&quot;tags-list&quot;&gt;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coq.html&quot; class=&quot;tag hover-lemon&quot; marked=&quot;&quot;&gt;coq&lt;/a&gt; &lt;/div&gt;
&lt;h2&gt;The Theory&lt;/h2&gt;
&lt;p&gt;If I had to explain &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt;, I would say &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt; is the heir of
the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt; tactic. It gives you a convenient way to embed proofs within
functional programs that are supposed to fade away during code extraction.  But
what do I mean when I say &quot;embed proofs&quot; within functional programs? I found
two ways to do it.&lt;/p&gt;
&lt;h3&gt;Invariants&lt;/h3&gt;
&lt;p&gt;First, we can define a record with one or more fields of type
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt;&lt;/code&gt;. By doing so, we can constrain the values of other fields. Put
another way, we can specify invariant for our type. For instance, in
&lt;a href=&quot;https://github.com/lthms/SpecCert&quot; class=&quot;hover-lavender&quot; marked=&quot;&quot;&gt;SpecCert&amp;nbsp;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#github&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/a&gt;, I have defined the memory
controller&apos;s SMRAMC register as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Record&lt;/span&gt; SmramcRegister := {
  d_open: bool;
  d_lock: bool;
  lock_is_close: d_lock = true -&amp;gt; d_open = false;
}.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So &lt;code class=&quot;hljs language-coq&quot;&gt;lock_is_closed&lt;/code&gt; is an invariant I know each instance of
&lt;code class=&quot;hljs&quot;&gt;SmramcRegister&lt;/code&gt; will have to comply with, because every time I
will construct a new instance, I will have to prove
&lt;code class=&quot;hljs language-coq&quot;&gt;lock_is_closed&lt;/code&gt; holds true. For instance:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; lock (reg: SmramcRegister)
  : SmramcRegister.
  &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; ({| &lt;span class=&quot;hljs-type&quot;&gt;d_open&lt;/span&gt; := false; d_lock := true |&lt;span class=&quot;hljs-type&quot;&gt;}).
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Coq leaves us this goal to prove.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;reg : SmramcRegister
============================
true = true -&amp;gt; false = false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This sound reasonable enough.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;trivial&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have seen in my previous article about strongly specified
functions that mixing proofs and regular terms may lead to
cumbersome code.&lt;/p&gt;
&lt;p&gt;From that perspective, &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt; helps. Indeed, the &lt;code class=&quot;hljs language-coq&quot;&gt;lock&lt;/code&gt; function
can also be defined as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; Coq &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;.

#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; lock&apos; (reg: SmramcRegister)
  : SmramcRegister :=
  {| &lt;span class=&quot;hljs-type&quot;&gt;d_open&lt;/span&gt; := false
   ; d_lock := true
   |&lt;span class=&quot;hljs-type&quot;&gt;}.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Pre and Post Conditions&lt;/h3&gt;
&lt;p&gt;Another way to &quot;embed proofs in a program&quot; is by specifying pre-
and post-conditions for its component. In Coq, this is done using
sigma types.&lt;/p&gt;
&lt;p&gt;On the one hand, a precondition is a proposition a function input has to
satisfy in order for the function to be applied.  For instance, a precondition
for &lt;code class=&quot;hljs language-coq&quot;&gt;head : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; {a}, list a -&amp;gt; a&lt;/code&gt; the function that returns the first
element of a list &lt;code class=&quot;hljs language-coq&quot;&gt;l&lt;/code&gt; requires &lt;code class=&quot;hljs language-coq&quot;&gt;l&lt;/code&gt; to contain at least one element.
We can write that using a sigma-type. The type of &lt;code class=&quot;hljs language-coq&quot;&gt;head&lt;/code&gt; then becomes
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; {a} (l: list a | &lt;span class=&quot;hljs-type&quot;&gt;l&lt;/span&gt; &amp;lt;&amp;gt; []) : a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On the other hand, a post condition is a proposition a function
output has to satisfy in order for the function to be correctly
implemented. In this way, &lt;code class=&quot;hljs&quot;&gt;head&lt;/code&gt; should in fact return the first
element of &lt;code class=&quot;hljs language-coq&quot;&gt;l&lt;/code&gt; and not something else.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt; makes writing this specification straightforward.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; head {a} (l : list a | &lt;span class=&quot;hljs-type&quot;&gt;l&lt;/span&gt; &amp;lt;&amp;gt; [])
  : { x : a | &lt;span class=&quot;hljs-type&quot;&gt;exists&lt;/span&gt; l&apos;, x :: l&apos; = l }.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We recall that because &lt;code class=&quot;hljs language-coq&quot;&gt;{ l: list a | &lt;span class=&quot;hljs-type&quot;&gt;l&lt;/span&gt; &amp;lt;&amp;gt; [] }&lt;/code&gt; is not the same as &lt;code class=&quot;hljs language-coq&quot;&gt;list a&lt;/code&gt;, in theory we cannot just compare &lt;code class=&quot;hljs language-coq&quot;&gt;l&lt;/code&gt; with &lt;code class=&quot;hljs language-coq&quot;&gt;x :: l&apos;&lt;/code&gt; (we need to
use &lt;code class=&quot;hljs language-coq&quot;&gt;proj1_sig&lt;/code&gt;). One advantage of &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt; is to deal with it using
an implicit coercion.&lt;/p&gt;
&lt;p&gt;Note that for the type inference to work as expected, the
unwrapped value (here, &lt;code class=&quot;hljs language-coq&quot;&gt;x :: l&apos;&lt;/code&gt;) needs to be the left operand of
&lt;code class=&quot;hljs language-coq&quot;&gt;=&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now that &lt;code class=&quot;hljs language-coq&quot;&gt;head&lt;/code&gt; have been specified, we have to implement it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; head {a} (l: list a | &lt;span class=&quot;hljs-type&quot;&gt;l&lt;/span&gt; &amp;lt;&amp;gt; [])
  : { x : a | &lt;span class=&quot;hljs-type&quot;&gt;exists&lt;/span&gt; l&apos;, cons x l&apos; = l } :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;x&lt;/span&gt; :: l&apos; =&amp;gt; x
  | &lt;span class=&quot;hljs-type&quot;&gt;[] =&amp;gt; !
  end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;exists&lt;/span&gt; l&apos;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I want to highlight several things here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We return &lt;code class=&quot;hljs language-coq&quot;&gt;x&lt;/code&gt; (of type &lt;code class=&quot;hljs language-coq&quot;&gt;a&lt;/code&gt;) rather than a sigma-type, then
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt; is smart enough to wrap it. To do so, it tries to prove the post
condition and because it fails, we have to do it ourselves (this is the
Obligation we solve after the function definition.)&lt;/li&gt;
&lt;li&gt;The &lt;code class=&quot;hljs language-coq&quot;&gt;[]&lt;/code&gt; case is absurd regarding the precondition, we tell Coq that
using the bang (&lt;code class=&quot;hljs language-coq&quot;&gt;!&lt;/code&gt;) symbol.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can have a look at the extracted code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;(** val head : &apos;a1 list -&amp;gt; &apos;a1 **)&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; head = &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;Nil&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;(* absurd case *)&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;Cons&lt;/span&gt; (a, _) -&amp;gt; a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The implementation is pretty straightforward, but the pre- and
post conditions have faded away. Also, the absurd case is
discarded using an assertion. This means one thing: [head] should
not be used directly from the Ocaml world. &quot;Interface&quot; functions
have to be total. *)&lt;/p&gt;
&lt;h2&gt;The Practice&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;From&lt;/span&gt; Coq &lt;span class=&quot;hljs-keyword&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Import&lt;/span&gt; Lia.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have challenged myself to build a strongly specified library. My goal was to
define a type &lt;code class=&quot;hljs language-coq&quot;&gt;vector : nat -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;&lt;/code&gt; such as &lt;code class=&quot;hljs language-coq&quot;&gt;vector a n&lt;/code&gt;
is a list of &lt;code class=&quot;hljs language-coq&quot;&gt;n&lt;/code&gt; instance of &lt;code class=&quot;hljs language-coq&quot;&gt;a&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; vector (a : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) : nat -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
| &lt;span class=&quot;hljs-type&quot;&gt;vcons&lt;/span&gt; {n} : a -&amp;gt; vector a n -&amp;gt; vector a (S n)
| &lt;span class=&quot;hljs-type&quot;&gt;vnil&lt;/span&gt; : vector a O.

&lt;span class=&quot;hljs-keyword&quot;&gt;Arguments&lt;/span&gt; vcons [a n] &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Arguments&lt;/span&gt; vnil {a}.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I had three functions in mind: &lt;code class=&quot;hljs language-coq&quot;&gt;take&lt;/code&gt;, &lt;code class=&quot;hljs language-coq&quot;&gt;drop&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;extract&lt;/code&gt;.
I learned a few lessons. My main takeaway remains: do not use sigma types,
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt; and dependent types together. From my point of view, Coq is not
yet ready for this. Maybe it is possible to make those three work together, but
I have to admit I did not find out how. As a consequence, my preconditions are
defined as extra arguments.&lt;/p&gt;
&lt;p&gt;To be able to specify the post conditions of my three functions and
some others, I first defined &lt;code class=&quot;hljs language-coq&quot;&gt;nth&lt;/code&gt; to get the &lt;em&gt;nth&lt;/em&gt; element of a
vector.&lt;/p&gt;
&lt;p&gt;My first attempt to write &lt;code class=&quot;hljs language-coq&quot;&gt;nth&lt;/code&gt; was a failure.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Fixpoint&lt;/span&gt; nth {a n}
    (v : vector a n) (i : nat) {struct v}
  : option a :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; v, i &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;vcons&lt;/span&gt; x &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;, O =&amp;gt; Some x
  | &lt;span class=&quot;hljs-type&quot;&gt;vcons&lt;/span&gt; x r, S i =&amp;gt; nth r i
  | &lt;span class=&quot;hljs-type&quot;&gt;vnil&lt;/span&gt;, &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; =&amp;gt; None
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;raised an anomaly.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Fixpoint&lt;/span&gt; nth {a n}
    (v : vector a n) (i : nat) {struct v}
  : option a :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; v &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;vcons&lt;/span&gt; x r =&amp;gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; i &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
    | &lt;span class=&quot;hljs-type&quot;&gt;O&lt;/span&gt; =&amp;gt; Some x
    | &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; i =&amp;gt; nth r i
    &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;vnil&lt;/span&gt; =&amp;gt; None
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With &lt;code class=&quot;hljs language-coq&quot;&gt;nth&lt;/code&gt;, it is possible to give a very precise definition of
&lt;code class=&quot;hljs language-coq&quot;&gt;take&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Fixpoint&lt;/span&gt; take {a n}
    (v : vector a n) (e : nat | &lt;span class=&quot;hljs-type&quot;&gt;e&lt;/span&gt; &amp;lt;= n)
  : { u : vector a e | &lt;span class=&quot;hljs-type&quot;&gt;forall&lt;/span&gt; i : nat,
        i &amp;lt; e -&amp;gt; nth u i = nth v i } :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; e &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; e&apos; =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; v &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
            | &lt;span class=&quot;hljs-type&quot;&gt;vcons&lt;/span&gt; x r =&amp;gt; vcons x (take r e&apos;)
            | &lt;span class=&quot;hljs-type&quot;&gt;vnil&lt;/span&gt; =&amp;gt; !
            &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;O&lt;/span&gt; =&amp;gt; vnil
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; le_S_n.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; i.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; e0.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; Lt.lt_S_n.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; PeanoNat.Nat.nle_succ_0 &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; H.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; PeanoNat.Nat.nlt_0_r &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; H.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a side note, I wanted to define the post condition as follows:
&lt;code class=&quot;hljs language-coq&quot;&gt;{ v&apos;: vector A e | &lt;span class=&quot;hljs-type&quot;&gt;forall&lt;/span&gt; (i : nat | &lt;span class=&quot;hljs-type&quot;&gt;i&lt;/span&gt; &amp;lt; e), nth v&apos; i = nth v i }&lt;/code&gt;. However, this made the goals and hypotheses become very hard
to read and to use. Sigma types in sigma types: not a good
idea.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;(** val take : &apos;a1 vector -&amp;gt; nat -&amp;gt; &apos;a1 vector **)&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;rec&lt;/span&gt; take v = &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;O&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-type&quot;&gt;Vnil&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; e&apos; -&amp;gt;
  (&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; v &lt;span class=&quot;hljs-keyword&quot;&gt;with&lt;/span&gt;
   | &lt;span class=&quot;hljs-type&quot;&gt;Vcons&lt;/span&gt; (_, x, r) -&amp;gt; &lt;span class=&quot;hljs-type&quot;&gt;Vcons&lt;/span&gt; (e&apos;, x, (take r e&apos;))
   | &lt;span class=&quot;hljs-type&quot;&gt;Vnil&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;(* absurd case *)&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I could tackle &lt;code class=&quot;hljs&quot;&gt;drop&lt;/code&gt; in a very similar manner:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Fixpoint&lt;/span&gt; drop {a n}
    (v : vector a n) (b : nat | &lt;span class=&quot;hljs-type&quot;&gt;b&lt;/span&gt; &amp;lt;= n)
  : { v&apos;: vector a (n - b) | &lt;span class=&quot;hljs-type&quot;&gt;forall&lt;/span&gt; i,
        i &amp;lt; n - b -&amp;gt; nth v&apos; i = nth v (b + i) } :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; b &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;0&lt;/span&gt; =&amp;gt; v
  | &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; n =&amp;gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; v &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
           | &lt;span class=&quot;hljs-type&quot;&gt;vcons&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; r =&amp;gt; (drop r n)
           | &lt;span class=&quot;hljs-type&quot;&gt;vnil&lt;/span&gt; =&amp;gt; !
           &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;)
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- Minus.minus_n_O.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; n;
    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- eq_rect_eq;
    &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; le_S_n.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; PeanoNat.Nat.nle_succ_0 &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; H.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The proofs are easy to write, and the extracted code is exactly what one might
want it to be:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;(** val drop : &apos;a1 vector -&amp;gt; nat -&amp;gt; &apos;a1 vector **)&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;rec&lt;/span&gt; drop v = &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;O&lt;/span&gt; -&amp;gt; v
| &lt;span class=&quot;hljs-type&quot;&gt;S&lt;/span&gt; n -&amp;gt;
  (&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; v &lt;span class=&quot;hljs-keyword&quot;&gt;with&lt;/span&gt;
   | &lt;span class=&quot;hljs-type&quot;&gt;Vcons&lt;/span&gt; (_, _, r) -&amp;gt; drop r n
   | &lt;span class=&quot;hljs-type&quot;&gt;Vnil&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;(* absurd case *)&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt; really shone when it comes to implementing extract. I just
had to combine &lt;code class=&quot;hljs language-coq&quot;&gt;take&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;drop&lt;/code&gt;. *)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; extract {a n} (v : vector a n)
    (e : nat | &lt;span class=&quot;hljs-type&quot;&gt;e&lt;/span&gt; &amp;lt;= n) (b : nat | &lt;span class=&quot;hljs-type&quot;&gt;b&lt;/span&gt; &amp;lt;= e)
  : { v&apos;: vector a (e - b) | &lt;span class=&quot;hljs-type&quot;&gt;forall&lt;/span&gt; i,
        i &amp;lt; (e - b) -&amp;gt; nth v&apos; i = nth v (b + i) } :=
  take (drop v b) (e - b).


&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;transitivity&lt;/span&gt; e; &lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; PeanoNat.Nat.sub_le_mono_r.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; drop; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; *.
  &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; take; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; *.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; e1; &lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; &amp;lt;- e0; &lt;span class=&quot;hljs-built_in&quot;&gt;auto&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;lia&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The proofs are straightforward because the specifications of &lt;code class=&quot;hljs language-coq&quot;&gt;drop&lt;/code&gt; and
&lt;code class=&quot;hljs language-coq&quot;&gt;take&lt;/code&gt; are precise enough, and we do not need to have a look at their
implementations. The extracted version of &lt;code class=&quot;hljs language-coq&quot;&gt;extract&lt;/code&gt; is as clean as we can
anticipate.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;(** val extract : &apos;a1 vector -&amp;gt; nat -&amp;gt; nat -&amp;gt; &apos;a1 vector **)&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; extract v e b =
  take (drop v b) (sub e b)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I was pretty happy, so I tried some more. Each time, using &lt;code class=&quot;hljs language-coq&quot;&gt;nth&lt;/code&gt;, I managed
to write a precise post condition and to prove it holds true. For instance,
given &lt;code class=&quot;hljs language-coq&quot;&gt;map&lt;/code&gt; to apply a function &lt;code class=&quot;hljs language-coq&quot;&gt;f&lt;/code&gt; to each element of a vector &lt;code class=&quot;hljs language-coq&quot;&gt;v&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Fixpoint&lt;/span&gt; map {a b n} (v : vector a n) (f : a -&amp;gt; b)
  : { v&apos;: vector b n | &lt;span class=&quot;hljs-type&quot;&gt;forall&lt;/span&gt; i,
        nth v&apos; i = option_map f (nth v i) } :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; v &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;vnil&lt;/span&gt; =&amp;gt; vnil
  | &lt;span class=&quot;hljs-type&quot;&gt;vcons&lt;/span&gt; a v =&amp;gt; vcons (f a) (map v f)
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; i.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; e.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I also managed to specify and write &lt;code class=&quot;hljs language-coq&quot;&gt;append&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;#[program]
Fixpoint append {a n m}
    (v : vector a n) (u : vector a m)
  : { w : vector a (n + m) | forall i,
        (i &amp;lt; n -&amp;gt; nth w i = nth v i) /\
        (n &amp;lt;= i -&amp;gt; nth w i = nth u (i - n))
    } :=
  match v with
  | vnil =&amp;gt; u
  | vcons a v =&amp;gt; vcons a (append v u)
  end.

Next Obligation.
  split.
  + now intro.
  + intros _.
    now rewrite PeanoNat.Nat.sub_0_r.
Defined.

Next Obligation.
  rename wildcard&apos; into n.
  destruct (Compare_dec.lt_dec i (S n)); split.
  + intros _.
    destruct i.
    ++ reflexivity.
    ++ cbn.
       specialize (a1 i).
       destruct a1 as [a1 _].
       apply a1.
       auto with arith.
  + intros false.
    lia.
  + now intros.
  + intros ord.
    destruct i.
    ++ lia.
    ++ cbn.
       specialize (a1 i).
       destruct a1 as [_ a1].
       apply a1.
       auto with arith.
Defined.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, I tried to implement &lt;code class=&quot;hljs language-coq&quot;&gt;map2&lt;/code&gt; that takes a vector of &lt;code class=&quot;hljs language-coq&quot;&gt;a&lt;/code&gt;, a vector of
&lt;code class=&quot;hljs language-coq&quot;&gt;b&lt;/code&gt; (both of the same size) and a function &lt;code class=&quot;hljs language-coq&quot;&gt;f : a -&amp;gt; b -&amp;gt; c&lt;/code&gt; and returns a
vector of &lt;code class=&quot;hljs language-coq&quot;&gt;c&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;First, we need to provide a precise specification for &lt;code class=&quot;hljs language-coq&quot;&gt;map2&lt;/code&gt;. To do that, we
introduce &lt;code class=&quot;hljs language-coq&quot;&gt;option_app&lt;/code&gt;, a function that Haskellers know all to well as being
part of the &lt;code class=&quot;hljs language-haskell&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;Applicative&lt;/span&gt;&lt;/code&gt; type class.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; option_app {a b}
    (opf: option (a -&amp;gt; b))
    (opx: option a)
  : option b :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; opf, opx &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;Some&lt;/span&gt; f, Some x =&amp;gt; Some (f x)
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt;, &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; =&amp;gt; None
&lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We thereafter use &lt;code class=&quot;hljs language-coq&quot;&gt;&amp;lt;$&amp;gt;&lt;/code&gt; as an infix operator for &lt;code class=&quot;hljs language-coq&quot;&gt;option_map&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;&amp;lt;*&amp;gt;&lt;/code&gt; as
an infix operator for &lt;code class=&quot;hljs language-coq&quot;&gt;option_app&lt;/code&gt;. *)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Infix&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&amp;lt;$&amp;gt;&quot;&lt;/span&gt; := option_map (&lt;span class=&quot;hljs-built_in&quot;&gt;at&lt;/span&gt; level &lt;span class=&quot;hljs-number&quot;&gt;50&lt;/span&gt;).
&lt;span class=&quot;hljs-keyword&quot;&gt;Infix&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&amp;lt;*&amp;gt;&quot;&lt;/span&gt; := option_app (&lt;span class=&quot;hljs-built_in&quot;&gt;at&lt;/span&gt; level &lt;span class=&quot;hljs-number&quot;&gt;55&lt;/span&gt;).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Given two vectors &lt;code class=&quot;hljs language-coq&quot;&gt;v&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;u&lt;/code&gt; of the same size and a function &lt;code class=&quot;hljs language-coq&quot;&gt;f&lt;/code&gt;, and given
&lt;code class=&quot;hljs language-coq&quot;&gt;w&lt;/code&gt; the result computed by &lt;code class=&quot;hljs language-coq&quot;&gt;map2&lt;/code&gt;, then we can propose the following
specification for &lt;code class=&quot;hljs language-coq&quot;&gt;map2&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (i : nat), nth w i = f &amp;lt;$&amp;gt; nth v i &amp;lt;*&amp;gt; nth u i&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This reads as follows: the &lt;code class=&quot;hljs language-coq&quot;&gt;i&lt;/code&gt;th element of &lt;code class=&quot;hljs language-coq&quot;&gt;w&lt;/code&gt; is the result of applying
the &lt;code class=&quot;hljs language-coq&quot;&gt;i&lt;/code&gt;th elements of &lt;code class=&quot;hljs language-coq&quot;&gt;v&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;u&lt;/code&gt; to &lt;code class=&quot;hljs language-coq&quot;&gt;f&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It turns out implementing &lt;code class=&quot;hljs language-coq&quot;&gt;map2&lt;/code&gt; with the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt; framework has
proven to be harder than I originally expected. My initial attempt was the
following:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Fixpoint&lt;/span&gt; map2 {a b c n}
    (v : vector a n) (u : vector b n)
    (f : a -&amp;gt; b -&amp;gt; c) {struct v}
  : { w: vector c n | &lt;span class=&quot;hljs-type&quot;&gt;forall&lt;/span&gt; i,
        nth w i = f &amp;lt;$&amp;gt; nth v i &amp;lt;*&amp;gt; nth u i
    } :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; v, u &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;vcons&lt;/span&gt; x rst, vcons x&apos; rst&apos; =&amp;gt;
      vcons (f x x&apos;) (map2 rst rst&apos; f)
  | &lt;span class=&quot;hljs-type&quot;&gt;vnil&lt;/span&gt;, vnil =&amp;gt; vnil
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt;, &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; =&amp;gt; !
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;Illegal application:
The term &quot;@eq&quot; of type &quot;forall A : Type, A -&amp;gt; A -&amp;gt; Prop&quot;
cannot be applied to the terms
 &quot;nat&quot; : &quot;Set&quot;
 &quot;S wildcard&apos;&quot; : &quot;nat&quot;
 &quot;b&quot; : &quot;Type&quot;
The 3rd term has type &quot;Type&quot; which should be coercible
to &quot;nat&quot;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So I had to fallback to defining the function in pure Ltac.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Fixpoint&lt;/span&gt; map2 {a b c n}
    (v : vector a n) (u : vector b n)
    (f : a -&amp;gt; b -&amp;gt; c) {struct v}
  : { w: vector c n | &lt;span class=&quot;hljs-type&quot;&gt;forall&lt;/span&gt; i,
        nth w i = f &amp;lt;$&amp;gt; nth v i &amp;lt;*&amp;gt; nth u i
    } := &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;.

&lt;span class=&quot;hljs-keyword&quot;&gt;Next&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Obligation&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;dependent&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; v; &lt;span class=&quot;hljs-built_in&quot;&gt;dependent&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; u.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;remember&lt;/span&gt; (IHv u f) &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; u&apos;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;inversion&lt;/span&gt; u&apos;.
    &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; (exist &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; (vcons (f a0 a1) x) &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;).
    &lt;span class=&quot;hljs-built_in&quot;&gt;intros&lt;/span&gt; i.
    &lt;span class=&quot;hljs-built_in&quot;&gt;induction&lt;/span&gt; i.
    * &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
    * &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; (H i).
  + &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; (exist &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; vnil &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;).
    &lt;span class=&quot;hljs-built_in&quot;&gt;reflexivity&lt;/span&gt;.
&lt;span class=&quot;hljs-keyword&quot;&gt;Qed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Is It Usable?&lt;/h2&gt;
&lt;p&gt;This post mostly gives the &quot;happy ends&quot; for each function. I think I tried
too hard for what I got in return and therefore I am convinced &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt;
is not ready (at least for a dependent type, I cannot tell for the rest). For
instance, I found at least one bug in Program logic (I still have to report
it). Have a look at the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;#[program]
&lt;span class=&quot;hljs-keyword&quot;&gt;Fixpoint&lt;/span&gt; map2 {a b c n}
     (u : vector a n) (v : vector b n)
     (f : a -&amp;gt; b -&amp;gt; c) {struct v}
  : vector c n :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; u &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; =&amp;gt; vnil
  &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It gives the following error:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;Error: Illegal application:
The term &quot;@eq&quot; of type &quot;forall A : Type, A -&amp;gt; A -&amp;gt; Prop&quot;
cannot be applied to the terms
 &quot;nat&quot; : &quot;Set&quot;
 &quot;0&quot; : &quot;nat&quot;
 &quot;wildcard&apos;&quot; : &quot;vector A n&apos;&quot;
The 3rd term has type &quot;vector A n&apos;&quot; which should be
coercible to &quot;nat&quot;.
&lt;/code&gt;&lt;/pre&gt;
        
      </description>
    </item>
    
    
    
    <item>
      <title>Implementing Strongly-Specified Functions with the refine Tactic</title>
      <link>https://soap.coffee/~lthms/posts/StronglySpecifiedFunctionsRefine.html</link>
      <guid>https://soap.coffee/~lthms/posts/StronglySpecifiedFunctionsRefine.html</guid>
      <pubDate>January 11, 2015</pubDate>
      <description>
        
        &lt;h1&gt;Implementing Strongly-Specified Functions with the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt; Tactic&lt;/h1&gt;&lt;div id=&quot;tags-list&quot;&gt;&lt;span class=&quot;icon&quot;&gt;&lt;svg&gt;&lt;use href=&quot;/~lthms/img/icons.svg#tag&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;/~lthms/tags/coq.html&quot; class=&quot;tag hover-lavender&quot; marked=&quot;&quot;&gt;coq&lt;/a&gt; &lt;/div&gt;
&lt;p&gt;I started to play with Coq, the interactive theorem prover
developed by Inria, a few weeks ago. It is a very powerful tool,
yet hard to master. Fortunately, there are some very good readings
if you want to learn (I recommend the Coq&apos;Art). This article is
not one of them.&lt;/p&gt;
&lt;p&gt;In this article, we will see how to implement strongly specified
list manipulation functions in Coq. Strong specifications are used
to ensure some properties on functions&apos; arguments and return
value. It makes Coq type system very expressive. Thus, it is
possible to specify in the type of the function &lt;code class=&quot;hljs language-coq&quot;&gt;pop&lt;/code&gt; that the return
value is the list passed as an argument in which the first element has been
removed, for example.&lt;/p&gt;
&lt;h2&gt;Is This List Empty?&lt;/h2&gt;
&lt;p&gt;It&apos;s the first question to deal with when manipulating
lists. There are some functions that require their arguments not
to be empty. It&apos;s the case for the &lt;code class=&quot;hljs language-coq&quot;&gt;pop&lt;/code&gt; function, for instance
it is not possible to remove the first element of a list that does
not have any elements in the first place.&lt;/p&gt;
&lt;p&gt;When one wants to answer such a question as “Is this list empty?”,
he has to keep in mind that there are two ways to do it: by a
predicate or by a boolean function. Indeed, &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;bool&lt;/code&gt; are
two different worlds that do not mix easily. One solution is to
write two definitions and to prove their equivalence.  That is
&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; args, predicate args &amp;lt;-&amp;gt; bool_function args = true&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Another solution is to use the &lt;code class=&quot;hljs language-coq&quot;&gt;sumbool&lt;/code&gt; type as middlemen. The
scheme is the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Defining &lt;code class=&quot;hljs language-coq&quot;&gt;predicate : args → &lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Defining &lt;code class=&quot;hljs language-coq&quot;&gt;predicate_dec : args -&amp;gt; { predicate args } + { ~predicate args }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Defining &lt;code class=&quot;hljs language-coq&quot;&gt;predicate_b&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; predicate_b (args) :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; predicate_dec args &lt;span class=&quot;hljs-keyword&quot;&gt;then&lt;/span&gt; true &lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt; false.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Defining the &lt;code class=&quot;hljs language-coq&quot;&gt;empty&lt;/code&gt; Predicate&lt;/h3&gt;
&lt;p&gt;A list is empty if it is &lt;code class=&quot;hljs language-coq&quot;&gt;[]&lt;/code&gt; (&lt;code class=&quot;hljs language-coq&quot;&gt;nil&lt;/code&gt;). It&apos;s as simple as that!&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; empty {a} (l : list a) : &lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt; := l = [].
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Defining a decidable version of &lt;code class=&quot;hljs language-coq&quot;&gt;empty&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;A decidable version of &lt;code class=&quot;hljs language-coq&quot;&gt;empty&lt;/code&gt; is a function which takes a list
&lt;code class=&quot;hljs language-coq&quot;&gt;l&lt;/code&gt; as its argument and returns either a proof that &lt;code class=&quot;hljs language-coq&quot;&gt;l&lt;/code&gt; is empty,
or a proof that &lt;code class=&quot;hljs language-coq&quot;&gt;l&lt;/code&gt; is not empty. This is encoded in the Coq
standard library with the &lt;code class=&quot;hljs language-coq&quot;&gt;sumbool&lt;/code&gt; type, and is written as
follows: &lt;code class=&quot;hljs language-coq&quot;&gt;{ empty l } + { ~ empty l }&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; empty_dec {a} (l : list a)
  : { empty l } + { ~ empty l }.
&lt;span class=&quot;hljs-keyword&quot;&gt;Proof&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
          | &lt;span class=&quot;hljs-type&quot;&gt;[] =&amp;gt; left&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;
          | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;
          &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;);
    &lt;span class=&quot;hljs-built_in&quot;&gt;unfold&lt;/span&gt; empty; &lt;span class=&quot;hljs-built_in&quot;&gt;trivial&lt;/span&gt;.
  &lt;span class=&quot;hljs-built_in&quot;&gt;unfold&lt;/span&gt; not; &lt;span class=&quot;hljs-built_in&quot;&gt;intro&lt;/span&gt; H; &lt;span class=&quot;hljs-built_in&quot;&gt;discriminate&lt;/span&gt; H.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, I decided to use the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt; tactic which is
convenient when we manipulate the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Set&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt;&lt;/code&gt; sorts at the
same time.&lt;/p&gt;
&lt;h3&gt;Defining &lt;code class=&quot;hljs language-coq&quot;&gt;empty_b&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;With &lt;code class=&quot;hljs language-coq&quot;&gt;empty_dec&lt;/code&gt;, we can define &lt;code class=&quot;hljs language-coq&quot;&gt;empty_b&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; empty_b {a} (l : list a) : bool :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; empty_dec l &lt;span class=&quot;hljs-keyword&quot;&gt;then&lt;/span&gt; true &lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt; false.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s try to extract &lt;code class=&quot;hljs language-coq&quot;&gt;empty_b&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;bool&lt;/span&gt; =
| &lt;span class=&quot;hljs-type&quot;&gt;True&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; sumbool =
| &lt;span class=&quot;hljs-type&quot;&gt;Left&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;Right&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;list&lt;/span&gt; =
| &lt;span class=&quot;hljs-type&quot;&gt;Nil&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;Cons&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; * &lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;list&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;(** val empty_dec : &apos;a1 list -&amp;gt; sumbool **)&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; empty_dec = &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;Nil&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-type&quot;&gt;Left&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;Cons&lt;/span&gt; (a, l0) -&amp;gt; &lt;span class=&quot;hljs-type&quot;&gt;Right&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;(** val empty_b : &apos;a1 list -&amp;gt; bool **)&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; empty_b l =
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; empty_dec l &lt;span class=&quot;hljs-keyword&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;Left&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-type&quot;&gt;True&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;Right&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-type&quot;&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In addition to &lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-symbol&quot;&gt;&apos;a&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;list&lt;/span&gt;&lt;/code&gt;, Coq has created the &lt;code class=&quot;hljs language-ocaml&quot;&gt;sumbool&lt;/code&gt; and
&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;bool&lt;/span&gt;&lt;/code&gt; types and &lt;code class=&quot;hljs language-ocaml&quot;&gt;empty_b&lt;/code&gt; is basically a translation from the
former to the latter. We could have stopped with &lt;code class=&quot;hljs language-ocmal&quot;&gt;empty_dec&lt;/code&gt;, but
&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;Left&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;Right&lt;/span&gt;&lt;/code&gt; are less readable that &lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;True&lt;/span&gt;&lt;/code&gt; and
&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;False&lt;/span&gt;&lt;/code&gt;. Note that it is possible to configure the Extraction mechanism
to use primitive OCaml types instead, but this is out of the scope of this
article.&lt;/p&gt;
&lt;h2&gt;Defining Some Utility Functions&lt;/h2&gt;
&lt;h3&gt;Defining &lt;code class=&quot;hljs language-coq&quot;&gt;pop&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;There are several ways to write a function that removes the first
element of a list. One is to return &lt;code class=&quot;hljs&quot;&gt;nil&lt;/code&gt; if the given list was
already empty:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; pop {a} ( l :list a) :=
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
  | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; :: l =&amp;gt; l
  | &lt;span class=&quot;hljs-type&quot;&gt;[] =&amp;gt; []
  end&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But it&apos;s not really satisfying. A &lt;code class=&quot;hljs&quot;&gt;pop&lt;/code&gt; call over an empty list should not be
possible. It can be done by adding an argument to &lt;code class=&quot;hljs&quot;&gt;pop&lt;/code&gt;: the proof that the
list is not empty.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; pop {a} (l : list a) (h : ~ empty l)
  : list a.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are, as usual when it comes to lists, two cases to
consider.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;l = x :: rst&lt;/code&gt;, and therefore &lt;code class=&quot;hljs language-coq&quot;&gt;pop (x :: rst) h&lt;/code&gt; is &lt;code class=&quot;hljs language-coq&quot;&gt;rst&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;l = []&lt;/code&gt;, which is not possible since we know &lt;code class=&quot;hljs language-coq&quot;&gt;l&lt;/code&gt; is not empty.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The challenge is to convince Coq that our reasoning is
correct. There are, again, several approaches to achieve that.  We
can, for instance, use the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt; tactic again, but this time we
need to know a small trick to succeed as using a “regular” &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt;&lt;/code&gt;
will not work.&lt;/p&gt;
&lt;p&gt;From the following goal:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;  a : Type
  l : list a
  h : ~ empty l
  ============================
  list a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt; tactic naively, for instance, this way:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
          | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; :: rst =&amp;gt; rst
          | &lt;span class=&quot;hljs-type&quot;&gt;[] =&amp;gt; _&lt;/span&gt;
          &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt;).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;leaves us the following goal to prove:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;  a : Type
  l : list a
  h : ~ empty l
  ============================
  list a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nothing has changed! Well, not exactly. See, &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt; has taken
our incomplete Gallina term, found a hole, done some
type-checking, found that the type of the missing piece of our
implementation is &lt;code class=&quot;hljs language-coq&quot;&gt;list a&lt;/code&gt; and therefore has generated a new
goal of this type.  What &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt; has not done, however, is
remembering that we are in the case where &lt;code class=&quot;hljs language-coq&quot;&gt;l = []&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We need to generate a goal from a hole wherein this information is
available. It is possible to use a long form of &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt;&lt;/code&gt;. The
general approach is this: rather than returning a value of type
&lt;code class=&quot;hljs language-coq&quot;&gt;list a&lt;/code&gt;, our match will return a function of type &lt;code class=&quot;hljs language-coq&quot;&gt;l = ?l&apos; -&amp;gt; list a&lt;/code&gt;, where &lt;code class=&quot;hljs language-coq&quot;&gt;?l&lt;/code&gt; is a value of &lt;code class=&quot;hljs language-coq&quot;&gt;l&lt;/code&gt; for a given case (that is,
either &lt;code class=&quot;hljs language-coq&quot;&gt;x :: rst&lt;/code&gt; or &lt;code class=&quot;hljs language-coq&quot;&gt;[]&lt;/code&gt;). Of course and as a consequence, the type
of the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt;&lt;/code&gt; in now a function which awaits a proof to return
the expected result. Fortunately, this proof is trivial: it is
&lt;code class=&quot;hljs language-coq&quot;&gt;eq_refl&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; l&apos;
                &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; l = l&apos; -&amp;gt; list a
          &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
          | &lt;span class=&quot;hljs-type&quot;&gt;_&lt;/span&gt; :: rst =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; =&amp;gt; rst
          | &lt;span class=&quot;hljs-type&quot;&gt;[] =&amp;gt; fun&lt;/span&gt; equ =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;
          &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt; eq_refl).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For us to conclude the proof, this is way better.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;  a : Type
  l : list a
  h : ~ empty l
  equ : l = []
  ============================
  list a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We conclude the proof, and therefore the definition of &lt;code class=&quot;hljs language-coq&quot;&gt;pop&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; equ &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; h.
  &lt;span class=&quot;hljs-built_in&quot;&gt;exfalso&lt;/span&gt;.
  now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; h.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&apos;s better and yet it can still be improved. Indeed, according to its type,
&lt;code class=&quot;hljs language-coq&quot;&gt;pop&lt;/code&gt; returns “some list.” As a matter of fact, &lt;code class=&quot;hljs language-coq&quot;&gt;pop&lt;/code&gt; returns “the
same list without its first argument.” It is possible to write
such precise definition thanks to sigma types, defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Inductive&lt;/span&gt; sig (A : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt;) (P : A -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;Prop&lt;/span&gt;) : &lt;span class=&quot;hljs-keyword&quot;&gt;Type&lt;/span&gt; :=
  exist : &lt;span class=&quot;hljs-keyword&quot;&gt;forall&lt;/span&gt; (x : A), P x -&amp;gt; sig P.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rather than &lt;code class=&quot;hljs language-coq&quot;&gt;sig A p&lt;/code&gt;, sigma-types can be written using the
notation &lt;code class=&quot;hljs language-coq&quot;&gt;{ a | &lt;span class=&quot;hljs-type&quot;&gt;P&lt;/span&gt; }&lt;/code&gt;. They express subsets, and can be used to constraint
arguments and results of functions.&lt;/p&gt;
&lt;p&gt;We finally propose a strongly specified definition of &lt;code class=&quot;hljs language-coq&quot;&gt;pop&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; pop {a} (l : list a | &lt;span class=&quot;hljs-type&quot;&gt;~ empty&lt;/span&gt; l)
  : { l&apos; | &lt;span class=&quot;hljs-type&quot;&gt;exists&lt;/span&gt; a, proj1_sig l = cons a l&apos; }.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you think the previous use of &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt;&lt;/code&gt; term was ugly, brace yourselves.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; proj1_sig l &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; l&apos;
                &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; proj1_sig l = l&apos;
                       -&amp;gt; { l&apos; | &lt;span class=&quot;hljs-type&quot;&gt;exists&lt;/span&gt; a, proj1_sig l = cons a l&apos; }
          &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
          | &lt;span class=&quot;hljs-type&quot;&gt;[] =&amp;gt; fun&lt;/span&gt; equ =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;
          | &lt;span class=&quot;hljs-type&quot;&gt;(_&lt;/span&gt; :: rst) =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; equ =&amp;gt; exist &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; rst &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;
          &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt; eq_refl).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This leaves us two goals to tackle.&lt;/p&gt;
&lt;p&gt;First, we need to discard the case where &lt;code class=&quot;hljs language-coq&quot;&gt;l&lt;/code&gt; is the empty list.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;  a : Type
  l : {l : list a | ~ empty l}
  equ : proj1_sig l = []
  ============================
  {l&apos; : list a | exists a0 : a, proj1_sig l = a0 :: l&apos;}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  + &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; [l nempty]; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; *.
    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; equ &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; nempty.
    &lt;span class=&quot;hljs-built_in&quot;&gt;exfalso&lt;/span&gt;.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; nempty.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, we need to prove that the result we provide (&lt;code class=&quot;hljs language-coq&quot;&gt;rst&lt;/code&gt;) when the
list is not empty is correct with respect to the specification of
&lt;code class=&quot;hljs language-coq&quot;&gt;pop&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs&quot;&gt;  a : Type
  l : {l : list a | ~ empty l}
  a0 : a
  rst : list a
  equ : proj1_sig l = a0 :: rst
  ============================
  exists a1 : a, proj1_sig l = a1 :: rst
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  + &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; [l nempty]; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; *.
    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; equ.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;exists&lt;/span&gt; a0.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&apos;s have a look at the extracted code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;(** val pop : &apos;a1 list -&amp;gt; &apos;a1 list **)&lt;/span&gt;

&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; pop = &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;Nil&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;(* absurd case *)&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;Cons&lt;/span&gt; (a, l0) -&amp;gt; l0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If one tries to call &lt;code class=&quot;hljs language-coq&quot;&gt;pop nil&lt;/code&gt;, the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;assert&lt;/span&gt;&lt;/code&gt; ensures the call fails. Extra
information given by the sigma type has been stripped away. It can be
confusing, and in practice it means that, we you rely on the extraction
mechanism to provide a certified OCaml module, you &lt;em&gt;cannot expose
strongly specified functions in its public interface&lt;/em&gt; because nothing in the
OCaml type system will prevent a misuse which will in practice leads to an
&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;&lt;/code&gt;. *)&lt;/p&gt;
&lt;h2&gt;Defining &lt;code class=&quot;hljs language-coq&quot;&gt;push&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;It is possible to specify &lt;code class=&quot;hljs language-coq&quot;&gt;push&lt;/code&gt; the same way &lt;code class=&quot;hljs language-coq&quot;&gt;pop&lt;/code&gt; has been. The only
difference is &lt;code class=&quot;hljs language-coq&quot;&gt;push&lt;/code&gt; accepts lists with no restriction at all. Thus, its
definition is a simpler, and we can write it without &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; push {a} (l : list a) (x : a)
  : { l&apos; | &lt;span class=&quot;hljs-type&quot;&gt;l&lt;/span&gt;&apos; = x :: l } :=
  exist &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; (x :: l) eq_refl.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the extracted code is just as straightforward.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; push l a =
  &lt;span class=&quot;hljs-type&quot;&gt;Cons&lt;/span&gt; (a, l)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Defining &lt;code class=&quot;hljs language-coq&quot;&gt;head&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Same as &lt;code class=&quot;hljs language-coq&quot;&gt;pop&lt;/code&gt; and &lt;code class=&quot;hljs language-coq&quot;&gt;push&lt;/code&gt;, it is possible to add extra information in the
type of &lt;code class=&quot;hljs language-coq&quot;&gt;head&lt;/code&gt;, namely the returned value of &lt;code class=&quot;hljs language-coq&quot;&gt;head&lt;/code&gt; is indeed the first value
of &lt;code class=&quot;hljs language-coq&quot;&gt;l&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Definition&lt;/span&gt; head {a} (l : list a | &lt;span class=&quot;hljs-type&quot;&gt;~ empty&lt;/span&gt; l)
  : { x | &lt;span class=&quot;hljs-type&quot;&gt;exists&lt;/span&gt; r, proj1_sig l = x :: r }.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&apos;s not a surprise its definition is very close to &lt;code class=&quot;hljs language-coq&quot;&gt;pop&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  &lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; proj1_sig l &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; l&apos;
                &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; proj1_sig l = l&apos; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;
          &lt;span class=&quot;hljs-built_in&quot;&gt;with&lt;/span&gt;
          | &lt;span class=&quot;hljs-type&quot;&gt;[] =&amp;gt; fun&lt;/span&gt; equ =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;
          | &lt;span class=&quot;hljs-type&quot;&gt;x&lt;/span&gt; :: &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; =&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;fun&lt;/span&gt; equ =&amp;gt; exist &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt; x &lt;span class=&quot;hljs-keyword&quot;&gt;_&lt;/span&gt;
          &lt;span class=&quot;hljs-keyword&quot;&gt;end&lt;/span&gt; eq_refl).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The proof is also very similar, and are left to read as an exercise for
passionate readers.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-coq&quot;&gt;  + &lt;span class=&quot;hljs-built_in&quot;&gt;destruct&lt;/span&gt; l &lt;span class=&quot;hljs-built_in&quot;&gt;as&lt;/span&gt; [l falso]; &lt;span class=&quot;hljs-built_in&quot;&gt;cbn&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; *.
    &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; equ &lt;span class=&quot;hljs-built_in&quot;&gt;in&lt;/span&gt; falso.
    &lt;span class=&quot;hljs-built_in&quot;&gt;exfalso&lt;/span&gt;.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;apply&lt;/span&gt; falso.
  + &lt;span class=&quot;hljs-built_in&quot;&gt;exists&lt;/span&gt; l0.
    now &lt;span class=&quot;hljs-built_in&quot;&gt;rewrite&lt;/span&gt; equ.
&lt;span class=&quot;hljs-keyword&quot;&gt;Defined&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, the extracted code is as straightforward as it can get.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;hljs language-ocaml&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; head = &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;Nil&lt;/span&gt; -&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;(* absurd case *)&lt;/span&gt;
| &lt;span class=&quot;hljs-type&quot;&gt;Cons&lt;/span&gt; (a, l0) -&amp;gt; a
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Writing strongly specified functions allows for reasoning about the result
correctness while computing it. This can help in practice. However, writing
these functions with the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;refine&lt;/span&gt;&lt;/code&gt; tactic does not enable a very idiomatic
Coq code.&lt;/p&gt;
&lt;p&gt;To improve the situation, the &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt; framework distributed with the
Coq standard library helps, but it is better to understand what &lt;code class=&quot;hljs language-coq&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;Program&lt;/span&gt;&lt;/code&gt;
achieves under its hood, which is basically what we have done in this article.&lt;/p&gt;
        
      </description>
    </item>
    
    
  </channel>
</rss>
