Require, Import, Require Import - import

In Coq, what's the difference between ... ?
Require X.
Import X.
Require Import X.
I have basically memorized some common patterns. I usually see code using Require Import X. Then there's Import ListNotation. And I just noticed it's also possible to write just Require X. What's the difference? Some practical examples would be appreciated.

Require loads a library whereas Import brings its definitions into scope. Require Import does both. If you only have the library loaded, you'll need to refer to names fully qualified. Coq allows top-level modules corresponding to files to define modules; these have to be imported separately to bring all of their definitions into scope, and they can't be Required - that's what's going on with ListNotations:
(* List is not loaded by default *)
Fail Check List.map.
(* the full name is technically Coq.Lists.List *)
Require List.
(* note that lists are actually defined in Coq.Init.Datatypes which is
imported by default, so [list] is unqualified and the [x::xs] notation is
already defined *)
Print List.map.
(*
List.map =
fun (A B : Type) (f : A -> B) =>
fix map (l : list A) : list B :=
match l with
| nil => nil
| (a :: t)%list => (f a :: map t)%list
end
: forall A B : Type, (A -> B) -> list A -> list B
*)
(* bring everything in List into scope *)
Import List.
(* this includes the ListNotations submodule *)
Import ListNotations.
(* note that now list notations are available, and the list notation scope is
open (from importing List) *)
Print List.map.
(*
map =
fun (A B : Type) (f : A -> B) =>
fix map (l : list A) : list B :=
match l with
| [] => []
| a :: t => f a :: map t
end
: forall A B : Type, (A -> B) -> list A -> list B
*)
Note there are some quirks with how Coq handles modules, especially compared to other languages:
Coq does not require a full path to a module, only an unambiguous suffix. Indeed I rarely see full import paths, even to standard library modules.
Notations cannot be used except by importing the module, and unlike most objects there's no way to refer to a notation, fully qualified or otherwise.
Importing a module can have side effects, for example changing notation interpretation scopes or setting options if you use Global Set in the module being imported.
Importing is fairly limited (especially compared to Haskell) - there's no way to rename a module at import time, or selectively import some definitions.

Related

How to solve the very simple Syntax error: 'end' expected after [branches] (in [term_match]). in Coq? (in Gallina and not ltac)

I was trying to write a very simple program to sum nats in a list (copy pasted from here):
Fixpoint sum (l : list nat) : nat :=
match l with
| [] => 0
| x :: xs => x + sum xs
end.
but my local Coq and jsCoq complain:
Syntax error: 'end' expected after [branches] (in [term_match]).
Why is this? (note I didn't even implement this but my implementation looks the same pretty much)
I've implemented recursive functions before:
Inductive my_nat : Type :=
| O : my_nat
| S : my_nat -> my_nat.
Fixpoint add_left (n m : my_nat) : my_nat :=
match n with
| O => m
| S n' => S (add_left n' m)
end.
which doesn't complain...
I did see this question How to match a "match" expression? but it seems to address some special issue in ltac and I am not using ltac.
The location of the error is on the [], which suggests that Coq does not understand that notation. Upon finding undefined notation, the parser has no idea what to do and produces an essentially meaningless error message.
To have standard list notation be defined, you need to import it from the standard library via:
Require Import List.
Import ListNotations.
The stdlib module List contains the module ListNotations, which defines [] (and more generally [ x ; y ; .. ; z ]). List also defines the notation x :: xs.
when picking up excerpts from a development, you also have to find what are the syntax changing commands that have an effect on this exceprts: Module importation, scope opening, argument declarations (for implicits), Notations, and coercions". In the current case, the file is actually provided by the author of the exercises through this pointer.

Best practices for parametrized Coq libraries

I'm writing a library in Coq that depends on user-supplied type parameters. One central part is a construction along the lines of
Require Import Ascii.
Require Import String.
Parameter UserType : Set. (* <<- placeholder for this example *)
Parameter UserToString : UserType -> string.
Inductive Tag : Set := TBool | TNat | TUser | TList : Tag -> Tag | TSum : Tag -> Tag -> Tag.
Fixpoint decodeT (t : Tag) : Set :=
match t with
| TBool => bool
| TNat => nat
| TUser => UserType (* <<- needed here *)
| TList t' => list (decodeT t')
| TSum l r => sum (decodeT l) (decodeT r)
end.
(* ...etc..., including: *)
Definition tostring (t : Tag) (v : decodeT t) : string := (* match t with ... end *) "dummy".
(* and other stuff *)
so I can't avoid those Parameters in some form. The whole library is split across multiple files, and because of the size it would be pretty uncomfortable to put everything in one file.
There's a top-level wrapper that exports all sub-modules. Ideally, I'd like to pass the parameters once when importing the library, and then this wrapper can do some magic to propagate them to all sub-modules, so that afterwards I don't have to worry about it anymore.
I've looked into various approaches, but nothing worked so far.
If I wrap the file contents in Sections, then the Parameters become extra arguments only on the definitions that use them, and then I have to manually splice them in everywhere when using the library's functions from outside.
If I don't wrap them in a Section, they are module parameters but I can't find a way to actually provide the value. (All forms of with Definition seem to require a module signature / Module Type? Duplicating all names & types to make an explicit signature would be prohibitively redundant, so maybe there is a way to make it work, but I couldn't find it. The documentation is also rather unhelpful...) Variations like using Context instead seem to have the same problem, as far as I tested things.
I'm happy to make a Module Type UserDefs (or typeclass, or whatever) that combines all the user definitions in a single value. I just don't know how to actually get it into the submodules.
So how do I do it? What needs to happen inside that sample file above, and what needs to happen on the outside, so that I can pass the definitions in once and then get a fully configured library to Import?
then I have to manually splice them in everywhere when using the library's functions from outside.
This is typically addressed by a mix of implicit parameters and type classes.
Declare a class for user-provided parameters.
Class UserParams : Type :=
{ UserType : Set
; UserToString : UserType -> string
}.
(* Make sure UserType and UserToString have UserParams as a maximally inserted implicit *)
Then in your library open sections parameterized by instances of that class:
Require Import Ascii.
Require Import String.
Section MyLib.
Context {userParams : UserParams}. (* Context generalizes Variable and allows you to set implicitness *)
Inductive Tag : Set := TBool | TNat | TUser | TList : Tag -> Tag | TSum : Tag -> Tag -> Tag.
Fixpoint decodeT (t : Tag) : Set :=
match t with
| TBool => bool
| TNat => nat
| TUser => UserType (* <<- needed here *)
| TList t' => list (decodeT t')
| TSum l r => sum (decodeT l) (decodeT r)
end.
(* ...etc..., including: *)
Definition tostring (t : Tag) (v : decodeT t) : string := (* match t with ... end *) "dummy".
(* and other stuff *)
End MyLib.
Then users instantiate the class
Require Import MyLib.
Instance myParams : UserParams :=
{| UserType := ...
; UserToString := ... |}.
And then your library functions will automatically be instantiated when you use them.

How does one print the entire contents of a proof object or Gallina terms in Coq?

How does one print and expand everything in a Coq term (e.g. implicits, notations, definition, everything)? I want to print absolutely everything (including the contents of the identifiers).
For example with a term, I tried a modest example with Set Printing All. but it didn't work as I expect. My script is:
Module print_everything.
Definition id {A:Type} (x:A) := x.
Print id.
Definition id2 := #id.
Print id2.
Set Printing All.
Print id2.
Print All.
End.
but when I sent it to coq I got:
id2 = #id
: forall (A : Type) (_ : A), A
but I expect the body of the function, something like this:
id2 = fun (A : Type) (x : A) => x
: forall (A : Type) (_ : A), A
or
id = fun (A : Type) (x : A) => x
: forall (A : Type) (_ : A), A
How does one remove all "abstractions", including notation, implicit and even identifiers
so that I can see the entire lambda term (ideally when passing a Gallina term to Print_everything)?
If possible I'd like to control the scopes of which definitions are unpacked for me too. e.g. global variables qualid . qualid.
How does one print and expand everything in a Coq term (e.g. implicits, notations, definition, everything)?
It would also be nice to be able to expand and simplify as much as possible.
Related:
How to temporarily disable notations in Coq
https://coq.discourse.group/t/how-to-unset-printing-everything-e-g-implicits-notations-etc/1364/4
it seems Show Proof. works in the middle of a proof: https://www.seas.upenn.edu/~cis500/cis500-f14/sf/ProofObjects.html and https://softwarefoundations.cis.upenn.edu/lf-current/ProofObjects.html

Import <Module> vs. Include <Module> in Coq Module system

What is the exact semantics of Include M1 inside another module, say M ? How is it different from doing Import M1 inside the module M ? More precisely what is the semantics of the following command:
Module Type M := M1 <+ M2 <+ M3.
To summarize the semantics of both vernacular commands:
The command Include M1 (which can be used in the definition of a module or a module type) asks Coq to make a copy of all the fields of M1. Thus, it acts just like a "copy-and-paste" of the contents of M1 inside the ambient module (resp. module type).
The command Import M1 (which can also be used in the definition of a module or a module type, but additionally requires that M1 is a module) allows one to refer to the fields of M1 with their short identifier (i.e., without needing to use qualified identifiers M1.field_name)
Next, the syntax Module Type M := M1 <+ M2 <+ M3 is a shortcut for:
Module Type M.
Include M1.
Include M2.
Include M3.
End M.
See the corresponding sections of Coq's reference manual on the Include and Import commands, and you may also want to take a look at the Export command (a variant of Import).
If at some point you hesitate between Include and Import, you should probably try to use Import in the first place, because it will have a lighter effect (it won't clone the contents of the specified module but just define shorter names).
Finally, below are two comprehensive examples that illustrate the use of modules, module types, and functors in Coq as well as the commands Include and Import:
(********************************************)
(* Example involving a parameterized module *)
(********************************************)
(* A signature *)
Module Type MT.
Parameter t : Type.
End MT.
(* A bigger signature *)
Module Type MT1.
Include MT.
Parameter u : t.
Parameter f : t -> t.
End MT1.
(* A parameterized module *)
Module F1 (M1 : MT1).
Import M1. (* => we can now write f rather than M1.f *)
Definition fu := f u.
End F1.
(* A module implementing MT1 *)
Module M1 <: MT1. (* => check the signature but don't make the module opaque *)
Definition t := nat.
Definition u := O.
Definition f := S.
End M1.
(* Instantiation *)
Module FM1 := F1 M1.
Compute FM1.fu.
and I recall that Compute is a shortcut for Eval vm_compute in
(********************************************)
(* Extra example: a parameterized signature *)
(* *)
(* It can be noted that this feature of Coq *)
(* module types has no equivalent in OCaml… *)
(********************************************)
Module Type MT2 (M : MT).
Parameter u : M.t.
Import M. (* => we can now write t rather than M.t *)
Parameter f : t -> t.
End MT2.
(* Another parameterized module *)
Module F2 (M : MT) (M2 : MT2 M).
Import M2.
Definition fu := f u.
End F2.
(* Modules implementing MT and MT2 *)
Module M <: MT.
Definition t := bool.
End M.
Module M2 <: MT2 M.
Definition u := false.
Definition f := negb.
End M2.
(* Instantiation *)
Module FM2 := F2 M M2.
Compute FM2.fu.

Working with semirings in Coq

This is a simple Coq syntax newbie question.:)
I am trying to define simple polynomial function on semi_rings:
Require Import Vector.
Import VectorNotations.
Require Import Ring_theory.
Section Polynomial_def.
Variable Asring : Type.
Variable (asr_0 asr_1 : Asring) (asr_add asr_mul: Asring->Asring->Asring).
Variable SRth : semi_ring_theory asr_0 asr_1 asr_add asr_mul eq.
Fixpoint evalPolynomial {n} (a: t Asring n) (x:Asring) : Asring :=
match a with
nil => asr_0
| cons a0 p a' => asr_add a0 (asr_mul x (evalPolynomial a' x))
end.
End Polynomial_def.
When I use it on Reals, for example, I have to do something like this:
Require Import Reals.Rdefinitions.
evalPolynomial R R0 Rplus Rmult a v
I suspect there should be a simpler syntax, where I can just pass single data structure (like comm_ring_1 in Isabelle) which will encapsulate all fields like R,R0,Rplus,Rmult for given type.
Yes, you can package all of your parameters in a structure and then pass that as an argument, something like
Structure semiring := Semiring {
Asring : Type;
asr_0 : Asring;
asr_1 : Asring;
asr_add : Asring -> Asring -> Asring
(* Other fields... *)
}.
Then, you can rephrase your development in terms of this structure:
Section Polynomial_def.
Variable sr := semiring.
Fixpoint evalPolynomial {n} (a: t (Asring sr) n) (x:Asring sr) : Asring sr :=
(* ... *)
Later, when trying to use that, you just have to build such a structure and pass it as a normal argument. You can also use Coq type classes or canonical structures to tell Coq how to pass such arguments automatically.