instantiate parameters to evaluate function definitions - coq

I'm working on a single .v file and I found it convenient to define things with parameters and definitions like this:
Parameter n : nat.
Definition n_plus_1 := n + 1.
rather than Definition n_plus_1 (n : nat) = n + 1.
My use cases are more complicated than this, but the idea is the same. Although defining things with parameters helped me write some proofs I'm interested in, sometimes I'd like to just test the definitions with actual values to make sure they actually compute what I intended. For example, with the example I just wrote, I can't do Compute n_plus_1 3. In some sense, I want to instantiate the parameter n. What'd be the best way to do it?

The quickest way is to use the Section mechanism [modules would also work]:
Section With_N.
Variable n : nat.
Definition n_plus_1 := n + 1.
End With_N.
Compute (n_plus_1 3).

Related

What is a concrete example of the type `Set` and what is the meaning of `Set`?

I've been trying to understand what Set is after encountering it in Adam Chlipala's book in addition to this great discussion in SO. His first example definition binary ops using Set:
Inductive binop : Set := Plus | Times.
in that book he says:
Second, there is the : Set fragment, which declares that we are defining a datatype that should be thought of as a constituent of programs.
Which confuses me. What does Adam mean here?
In addition, I thought that some additional concrete examples would help my understanding. I am not an expert of Coq so I am not sure what type of examples would help but something simple and very concrete/grounded might be useful.
Note, I have seen that Set is the first "type set" in a the type hierarchy e.g. Set = Type(0) <= Type = Type(1) <= Type(2) <= ... . I guess this sort of makes sense intuitively like I'd assume nat \in Type and all usual programming types to be in it but not sure what would be in Type that wouldn't be in Set. Perhaps recursive types? Not sure if that is the right example but I am trying to wrap my head around what this concept means and it's conceptual (& practical) usefulness.
Though Set and Type are different in Coq, this is mostly due to historical reasons. Nowadays, most developments do not rely on Set being different from Type. In particular, Adam's comment would also make sense if you replace Set by Type everywhere. The main point is that, when you want to define a datatype that you can compute with during execution (e.g. a number), you want to put it in Set or Type rather than Prop. This is because things that live in Prop are erased when you extract programs from Coq, so something defined in Prop would end up not computing anything.
As for your second question: Set is something that lives in Type, but not in Set, as the following snippet shows.
Check Set : Type. (* This works *)
Fail Check Set : Set.
(* The command has indeed failed with message: *)
(* The term "Set" has type "Type" while it is expected to have type *)
(* "Set" (universe inconsistency: Cannot enforce Set+1 <= Set). *)
This restriction is in place to prevent paradoxes in the theory. This is pretty much the only difference you see between Set and Type by default. You can also make them more different by invoking Coq with the -impredicative-set option:
(* Needs -impredicative-set; otherwise, the first line will also fail.*)
Check (forall A : Set, A -> A) : Set.
Universe u.
Fail Check (forall A : Type#{u}, A -> A) : Type#{u}.
(* The command has indeed failed with message: *)
(* The term "forall A : Type, A -> A" has type "Type#{u+1}" *)
(* while it is expected to have type "Type#{u}" (universe inconsistency: Cannot enforce *)
(* u < u because u = u). *)
Note that I had to add the Universe u. declaration to force the two occurrences of Type to be at the same level. Without this declaration, Coq would silently put the two Types at different universe levels, and the command would be accepted. (This would not mean that Type would have the same behavior as Set in this example, since Type#{u} and Type#{v} are different things when u and v are different!)
If you're wondering why this feature is useful, it is not by chance. The overwhelming majority of Coq developments does not rely on it. It is turned off by default because it is incompatible with a few axioms that are generally considered more useful in Coq developments, such as the strong law of the excluded middle:
forall A : Prop, {A} + {~ A}
With -impredicative-set turned on, this axiom yields a paradox, while it is safe to use by default.

Section mechanism in Coq. Forbid omitting of hypotheses from context

I need more primitive mechanism of generalization in sections.
For example,
Section sec.
Context (n:nat).
Definition Q:=bool.
End sec.
Check Q.
I will obtain Q : Set, but I need Q:nat->Set.
I've tried Context, Hypotheses, Variables. It doesn't work.
How to obtain such behavior?
This is not a thing you can do with Definition ... := However, you can use Proof using:
Section sec.
Context (n:nat).
Definition Q : Set.
Proof using n.
exact bool.
Defined.
End sec.
Check Q.

Finite list with unknown size

I'm a bit confused trying to define some structures using the math-comp library. I want to define a structure that has a function ranging from a set of values and returning lists of other values. I'm trying to define this structure as finType but it is failing (I assume it is because I am returning a list of unknown size).
For example:
Section MySection.
Variables F V : finType.
Structure m := M {
f : {ffun F -> seq V};
...
}.
(* Using the PcanXXXMixin family of lemmas *)
Lemma can_m_of_prod : cancel prod_of_m m_of_prod.
Proof. by case. Qed.
...
Definition m_finMixin := CanFinMixin can_m_of_prod.
This throws the error Unable to unify.
I think the issue is that I am using seq and this is not finite. I am not sure how to describe that it will only return finite lists. I thought I might use n-tuples but this would require specifying a size beforehand (I could include the size along with the F value perhaps? I'm not sure how that would look in this notation).
Is there something I am missing or is there another approach that seems more adequate?
Thanks in advance!
I suggest you specify the bound function directly on the type. This is for example used in Stefania Dumbrava's PhD to bound the maximum arity of a signature and works well if you know the trick:
f : {ffun n -> (bound ...).-tuple A}
Usually bound := \max_S ..., so it works well with the rest of the theory.

Best Practices for Dummy Values in Coq

I find that I'm frequently writing code like this:
Fixpoint get_fresh w (Γ : Ctx) : Pat w * Ctx:=
match w with
...
| w1 ⊗ w2 => let (p1, Γ1) := get_fresh w1 Γ in
match Γ ⋓ Γ1 with
| None => (dummy_pat _, dummy_ctx)
| Some Γ' => (p1,Γ')
end.
Where the None branch will never be entered. (Here, it's impossible to enter the branch, sometimes we will never enter the branch on an appropriate input.)
What's the best way to implement the dummy values that should never be returned?
An easy approach is to simply declare
Parameter dummy_pat : forall W, Pat W.
Parameter dummy_ctx : Ctx.
But that sounds seems like bad practice - for all the user knows Ctx and Pat W might have no inhabitants. (This is especially true for dependent types like Pat W.)
I could give simple definitions for dummy_pat and dummy_ctx but I don't want users reasoning about this branch. I could declare dummy_pat and dummy_ctx opaque, but opacity is disturbingly easy to reverse.
Finally, I guess I could declare these as the a projection from a sigma type, but it seems like that would be confusing, and I'm not sure it addresses the problem of reasoning about that case.
(Note that I don't want to intrinsically prove that these branches are inaccessible, using Program or otherwise. I find these functions very difficult to write and to use.)
Any suggestions?
The following way of declaring a module may have better opaqueness guarantees (but if I'm wrong I'd be very interested to know!):
Module Type DummySig.
Parameter dummy_pat : forall W, Pat W.
Parameter dummy_ctx : Ctx.
End DummySig.
Module Import Dummy : DummySig.
Definition dummy_pat := (* some simple definition *)
Definition dummy_ctx := (* some simple definition *)
End Dummy.
Explanation
Module Import Dummy : DummySig. is short for Module Dummy : DummySig followed by Import Dummy. after the closing End Dummy. command.
Module Dummy : DummySig. declares a module with module type (or signature) DummySig, and also seals the module so that only the information declared in DummySig is visible about this Dummy module.
This is a strong abstraction boundary that hides all of the implementation details. In particular, a Parameter in DummySig makes a definition opaque in Dummy, and identifiers defined in Dummy that do not appear in DummySig are not visible at all from outside the module.
As far as I can tell, this opaqueness is irreversible, which is the key point here.
For comparison, the two other ways of declaring modules are:
Module M. exposes everything in the module M, so it is mostly a kind of namespacing.
Module M <: MSig., also exposes everything in M, while checking that it implements the signature MSig (defined via Module Type MSig.), without the "sealing" aspect of Module M : Sig..
Other proposed solutions
You can also turn the dummies into actual parameters, either via a module functor...
Module MyProject (Dummy : DummySig).
Import Dummy.
...
or a section; to avoid having to pass dummies around, a type class may be useful.
Class Dummy (A : Type) := { dummy : A }.
Section Dummies.
Context `{forall W, Dummy (Pat W)}.
Context `{Dummy Ctx}.
...
At the end of the day I wonder whether it is really bad that users can reason about inaccessible branches.

How do you define an ordered pair in Coq?

I am a programmer, but an ultra-newbie to Coq, and have tried to figure out the tutorials without much success. My question is very simple: How does one define an ordered pair (of natural numbers) in Coq?
Here was my attempt:
Variable node1 : nat.
Variable node2 : nat.
Inductive edge : type := node1 -> node2.
(Note that "edge" is the name I am using for ordered pair.) The third line gives a syntax error, suggesting that I need a '.' in the sentence somewhere.
I don't know what to do. Any help would be great! (Also, is there a tutorial that helps teach very basic Coq concepts better than the ones that are easily seen given a Google search for "Coq Tutorial" ?)
You can do this simply enough by just using a Coq definition:
Definition ordered_pair := (nat * nat) % type.
This introduces ordered_pair as a synonym for (nat * nat) % type (note that the % type is required to get Coq to interpret * in the scope of types, rather than naturals). The real power is in the use of *:
Inductive prod (A B:Type) : Type :=
pair : A -> B -> prod A B.
(From http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html)
You get all the necessary elimination principles, etc... from there.