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

Related

What is the advantage of Option/Maybe Monad over Functor?

I understand the advantage of IO monad and List Monad over Functor, however, I don't understand the advantage of Option/Maybe Monad over Functor.
Is that simply the integration of types of the language?
or
What is the advantage of Option/Maybe Monad over Functor in specific use?
PS. asking the advantage in specific use is not opinion-based because if there is, it can be pointed out without subjective aspect.
PS.PS. some member here is so eager to push repeatedly
Option is both a functor and a monad?
should be the answer, or QA is duplicate, but actually not.
I already know the basics such as
Every monad is an applicative functor and every applicative functor is a functor
as the accepted answer there, and that is not what I'm not asking here.
Having an excellent answer here that is Not included in the previous QA.
The aspect, detail, or resolution of each question is quite different, so please avoid "bundling" different things in rough manner here.
Let's look at the types.
fmap :: Functor f => (a -> b) -> (f a -> f b)
(<*>) :: Applicative f => f (a -> b) -> (f a -> f b)
flip (>>=) :: Monad f => (a -> f b) -> (f a -> f b)
For a functor, we can apply an ordinary function a -> b to a value of type f a to get a value of type f b. The function never gets a say in what happens to the f part, only the inside. Thinking of functors as sort of box-like things, the function in fmap never sees the box itself, just the inside, and the value gets taken out and put back into the exact same box it started at.
An applicative functor is slightly more powerful. Now, we have a function which is also in a box. So the function gets a say in the f part, in a limited sense. The function and the input each have f parts (which are independent of each other) which get combined into the result.
A monad is even more powerful. Now, the function does not, a priori, have an f part. The function takes a value and produces a new box. Whereas in the Applicative case, our function's box and our value's box were independent, in the Monad case, the function's box can depend on the input value.
Now, what's all this mean? You've asked me to focus on Maybe, so let's talk about Maybe in the concrete.
fmap :: (a -> b) -> (Maybe a -> Maybe b)
(<*>) :: Maybe (a -> b) -> (Maybe a -> Maybe b)
flip (>>=) :: (a -> Maybe b) -> (Maybe a -> Maybe b)
As a reminder, Maybe looks like this.
data Maybe a = Nothing | Just a
A Maybe a is a value which may or may not exist. From a functor perspective, we'll generally think of Nothing as some form of failure and Just a as a successful result of type a.
Starting with fmap, the Functor instance for Maybe allows us to apply a function to the inside of the Maybe, if one exists. The function gets no say over the success or failure of the operation: A failed Maybe (i.e. a Nothing) must remain failed, and a successful one must remain successful (obviously, we're glossing over undefined and other denotational semantic issues here; I'm assuming that the only way a function can fail is with Nothing).
Now (<*>), the applicative operator, takes a Maybe (a -> b) and a Maybe a. Either of those two might have failed. If either of them did, then the result is Nothing, and only if the two both succeeded do we get a Just as our result. This allows us to curry operations. Concretely, if I have a function of the form g :: a -> b -> c and I have values ma :: Maybe a and mb :: Maybe b, then we might want to apply g to ma and mb. But when we start to do that, we have a problem.
fmap g ma :: Maybe (b -> c)
Now we've got a function that may or may not exist. We can't fmap that over mb, because a nonexistent function (a Nothing) can't be an argument to fmap. The problem is that we have two independent Maybe values (ma and mb in our example) which are fighting, in some sense, for control. The result should only exist if both are Just. Otherwise, the result should be Nothing. It's sort of a Boolean "and" operation, in that if any of the intermediates fail, then the whole calculation fails. (Note: If you're looking for a Boolean "or", where any individual success can recover from prior failure, then you're looking for Alternative)
So we write
(fmap g ma) <*> mb :: Maybe c
or, using the more convenient synonym Haskell provides for this purpose,
g <$> ma <*> mb :: Maybe c
Now, the key word in the above situation is independent. ma and mb have no say over the other's success or failure. This is good in many cases, because code like this can often be parallelized (there are very efficient command line argument parsing libraries that exploit just this property of Applicative). But, obviously, it's not always what we want.
Enter Monad. In the Maybe monad, the provided function produces a value of type Maybe b based on the input a. The Maybe part of the a and of the b are no longer independent: the latter can depend directly on the former.
For example, take the classic example of Maybe: a square root function. We can't take a square root of a negative number (let's assume we're not working with complex numbers here), so our hypothetical square root looks like
sqrt :: Double -> Maybe Double
sqrt x | x < 0 = Nothing
| otherwise = Just (Prelude.sqrt x)
Now, suppose we've got some number r. But r isn't just a number. It came from earlier in our computation, and our computation might have failed. Maybe it did a square root earlier, or tried to divide by zero, or something else entirely, but it did something that has some chance of producing a Nothing. So r is Maybe Double, and we want to take its square root.
Obviously, if r is already Nothing, then its square root is Nothing; we can't possibly take a square root if we've already failed to compute everything else. On the other hand, if r is a negative number, then sqrt is going to fail and produce Nothing despite the fact that r is itself Just. So what we really want is
case r of
Nothing -> Nothing
Just r' -> sqrt r'
And this is exactly what the Monad instance for Maybe does. That code is equivalent to
r >>= sqrt
The result of this entire computation (and, namely, whether or not it is Nothing or Just) depends not just on whether or not r is Nothing but also on r's actual value. Two different Just values of r can produce success or failure depending on what sqrt does. We can't do that with just a Functor, we can't even do that with Applicative. It takes a Monad.

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.

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.

General Advice about When to Use Prop and When to use bool

I am formalizing a grammar which is essentially one over boolean expressions. In coq, you can get boolean-like things in Prop or more explicitly in bool.
So for example, I could write:
true && true
Or
True /\ True
The problem is that in proofs (which is what I really care about) I can do a case analysis in domain bool, but in Prop this is not possible (since all members are not enumerable, I suppose). Giving up this tactic and similar rewriting tactics seems like a huge drawback even for very simple proofs.
In general, what situations would one choose Prop over bool for formalizing? I realize this is a broad question, but I feel like this is not addressed in the Coq manual sufficiently. I am interested in real world experience people have had going down both routes.
There are lots of different opinions on this. My personal take is that you are often better off not making this choice: it makes sense to have two versions of a property, one in Prop, the other one in bool.
Why would you want this? As you pointed out, booleans support case analysis in proofs and functions, which general propositions do not. However, Prop is more convenient to use in certain cases. Suppose you have a type T with finitely many values. We can write a procedure
all : (T -> bool) -> bool
that decides whether a boolean property P : T -> bool holds of all elements of T. Imagine that we know that all P = true, for some property P. We might want to use this fact to conclude that P x = true for some value x. To do this, we need to prove a lemma about all:
allP : forall P : T -> bool,
all P = true <-> (forall x : T, P x = true)
This lemma connects two different formulations of the same property: a boolean one and a propositional one. When reasoning about all in a proof, we can invoke allP to convert freely between the two. We can also have different conversion lemmas:
allPn : forall P,
all P = false <-> (exists x, P x = false)
In fact, we are free to choose any Coq proposition whatsoever to relate to a boolean computation (as long, of course, as we can prove that the two are logically equivalent). For instance, if we would like to have a custom induction principle associated with a boolean property, we can look for an equivalent formulation as an inductively defined proposition.
The Mathematical Components library is a good example of development that follows this style. Indeed, because it is so pervasive there, the library provides a special view mechanism for writing conversion lemmas like the one above and applying them. In plain Coq, we can also use the rewrite tactic to apply logical equivalences more conveniently.
Of course, there are many situations where it does not make sense to have two formulations of the same property. Sometimes, you are forced to use Prop, because the property you care about is undecidable. Sometimes, you might feel that you wouldn't gain anything by writing your property in Prop, and may keep it only as a boolean.
In addition to the Software Foundations chapter linked above, this answer discusses the difference between bool and Prop in more depth.

Coq: adding implicit variables

Suppose that I have a set of functions, each of which can depend on one or two implicit variables A B: Type. How can I specify this? I.e. add these variables to their variable list and set them as implicit.
The most obvious way is to add {A B: Type} to their definitions. However, in real life and moderately complicated developments such shared lists of implicits can easily be 6-10 entries long and include complicated types, thus making function definitions hard to read and even harder to understand their similarity or make change to mentioned types. Thus this solution is not applicable.
I could include all functions in a section or module and write Variables (A B: Type) etc in the beginning, but that would not make variables implicit and I would have to manually set arguments for all functions at the end of section. Even worse, that would make all variables shared. I.e. if I declare
Section sect.
Variable A B: Type.
Definition f (t: A -> Type) := (..).
Definition g (t: A -> Type) (s: B -> Type) := G (f t) (f s).
End sect.
(G is some two-variable function) then g would not be accepted, since s is not in A -> Type, even though essentially f requires only an arbitrary type family.
I could make a section and declare Context {A B: Type}. That would make those variables implicit for all functions, but the sharing problem like in previous case would still remain. Thus I would have to arbitrarily split my functions into several sections so that I could call functions from Sect.1 with different values of their implicit arguments. This works, but is ugly, and I can easily imagine a situation where each section would have to be 2-3 functions long just so that I could call them properly.
Is there a better solution?
There are two things you can do that are less difficult:
Generalizable All Variables.
Definition g `(t: A -> Type) `(s: B -> Type) := G (f t) (f s).
Now you can use backtick, and it will automatically insert the implicit variables you need to make the definition valid. This is the most common way that I introduce implicits.
The other way is to follow your section with:
Arguments g : default implicits.
You'll need to repeat this for every defined term, but at least you don't need to name all of the arguments.