Best Practices for Dummy Values in Coq - 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.

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.

In the Verified Software Toolchain, how can I specify some Clight which is not the body of a function, and which I'm generating from within Coq?

I would like to write a Gallina function of a type like gen_code : Foo -> statement and then prove that it generates code that satisfies a particular specification. I do have an informal Hoare triple in mind; however, I'm not terribly familiar yet with VST, and I'm not sure exactly how to turn it something that the framework can work with. I think I want a theorem of the form forall {Espec : OracleKind} (foo : Foo), semax ?Delta (P foo) (gen_code foo) (normal_ret_assert (Q foo)), where I know what P and Q are, but I'm not sure what to put for ?Delta. It's worth noting that I have some functions defined in C that I've verified already which I want to invoke from the code generated by gen_code, so presumably ?Delta needs to involve the signatures of those somehow. I assume it probably also needs to mention the free variables of gen_code foo, and here I'm similarly lost.

Specialization of module argument in Coq

I have a module and I need to specialize one of its argument. I want to use natural numbers instead of arbitrary UsualDecidableTypeFull. How can I obtain such behaviour in Coq?
I defined some module:
Module PRO2PRE_mod
(SetVars FuncSymb PredSymb PropSymb: UsualDecidableTypeFull).
(* ... *)
End PRO2PRE_mod.
Then I specialized the last of the arguments PropSymb.
Require Import Arith.PeanoNat.
Module m2 : UsualDecidableTypeFull.
Definition t:=nat.
Definition eq := #eq nat.
Definition eq_refl:=#eq_refl nat.
Definition eq_sym:=#eq_sym nat.
Definition eq_trans:=#eq_trans nat.
Definition eq_equiv:Equivalence eq := Nat.eq_equiv.
Definition eq_dec := Nat.eq_dec.
Definition eqb:=Nat.eqb.
Definition eqb_eq:=Nat.eqb_eq.
End m2.
This module needs specialization of PropVars:
Module SWAP_mod
(SetVars FuncSymb PredSymb : UsualDecidableTypeFull).
Module PRE := PRO2PRE_mod SetVars FuncSymb PredSymb m2.
Import PRE.
Theorem test : m2.t.
try exact 0. (* ERROR HERE! *)
Abort.
End SWAP_mod.
How to use theorems about natural numbers inside the last module? (I think I don't understand something about using modules... Maybe we need somehow to coerce the type 'm2.t' to the type 'nat'?)
Indeed, the use of : UsualDecidableTypeFull in the definition of m2 hides completely the implementation details of m2. From the outside, m2.t is an unknown type.
Sometimes, this is exactly what you want. For example, you may want to abstract away a type defined in a module so that the users cannot manipulate values of this type without using the functions that you gave to them in the module. You can thus ensure that they will not break some invariants.
However, in your case, you need to remember that m2.t is actually nat, you have at least these two options:
Make the interface transparent with Module m2 <: UsualDecidableTypeFull. When using this, Coq just verifies that the definition of the module complies with the signature, but does not hide the content of the module.
If you still want to hide part of the module, you can also use
Module m2 : UsualDecidableTypeFull with Definition t := nat.
In this case, from the outside, m2.t is known to be nat, but the other fields of m are masked. For instance, the body of m2.eqb is hidden.

define a "dependently typed" module functor

How can I make a dependently typed functor (for lack of a better term) ? I want to do something like the following:
Module Type Element.
...
End Element.
Module Wrapper (E : Element).
...
End Wrapper.
Module DepentlyTypedFunctor (E : Element) (W : Wrapper E).
...
End DepentlyTypedFunctor.
The last definition doesn't work, and I guess I'm looking for the correct syntax, if possible at all. My motivation for this kind of definition is to define theorems inside DependentlyTypedFunctor that work for all Wrappers that contain any instance of Element, similar to how one could define a theorem for vectors, forall (E : Element) (W : Wrapper E), some_proposition E W.
I think you just meant to make Wrapper a Module Type. If it's not a module type, there's only one such module and you can just write DependentlyTypedFunctor over E. This might not be sufficient if you have opaque implementations of Element, though, in which case different instantiations of Wrapper might not be equal to each other.
If this is a problem, you might just want to use records instead of modules.

instantiate parameters to evaluate function definitions

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).