-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stdlib #423
Stdlib #423
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
I suggest you run git rebase -i --exec "dune runtest --auto-promote; dune fmt" main
. This will put the PR in a cleaner state, render the last commit unnecessary and move the ocaml-ci
to green.
On the topic of CI, this PR definitely deserve a changelog!
I see you didn't include the Coq/Rocq proof. I would have been at least curious, and I think it could make sense to include it in the repo.
Regarding commit messages, I suggest we follow these good practices.
They are pretty common and already followed by a non-negligible subset of the commits of this repo.
Now, regarding Gospel formatting, I believe
In commit 44ec14c
, you introduce a white space in the signature of integer_of_int
at the level of the argument, this is not consistent with the previous style, nor it is a general modification of style. This also has no logical connection with the topic of the commit.
As a general remark about formatting, I feel we lack consistency. This is not just an aesthetic consideration, a consistent formatting will help the reader.
For example, we have three different formatting styles here:
(*@ axiom append_elems_right :
forall s s' i.
length s <= i < length s + length s' ->
(s ++ s')[i] = s'[i - length s] *)
(*@ axiom subseq_l :
forall s i. 0 <= i < length s -> s[i ..] = s[i .. length s] *)
(*@ axiom subseq : forall s i i1 i2.
0 <= i1 <= i < i2 <= length s -> s[i] = (s[i1 .. i2])[i-i1] *)
My personal preference goes to the first with:
- quantification on the first line
- one antecedent per line (I personally like the arrow at the beginning of the line)
- conclusion on the last line
Some functions are just declared and their semantic is given in the form of axioms, and other are implemented.
I guess it is to minimize the amount of Coq/Rocq proof?
Still, it is a bit surprising for the reader, letting them wonder about whether this is an interface, an implementation file, something else?
The reader also has to switch between reading logical axiom and implementation while going through the standard library, this is not the most pleasant experience.
Some module documentation with some explanation about the purpose of this standard library and how the semantic of the symbols is defined could do a lot of good.
In order to homogenize how the semantic of functions are defined, maybe we could just declare the one that are, at the moment of this review, implemented, and use the implementation term in an axiom? Would this generate too much rework on the Coq/Rocq side?
For example:
(*@ function singleton (x: 'a) : 'a t = init 1 (fun _ -> x) *)
Would become:
(*@ function singleton (x: 'a) : 'a t *)
(*@ axiom singletion_definition :
forall x.
singletion x = init 1 (fun _ -> x) *)
This would also have the benefit of letting tools needing an implementation (i.e Ortac) free of choosing an efficient one.
For example, the following implementation of Sequence.mem
is clearly not what we want in the context of dynamic verification:
(*@ predicate mem (x: 'a) (s: 'a t) = multiplicity x s > 0 *)
I'm still not convinced about using the arrow type for maps
. But I guess this is a design question and it has been already discussed elsewhere.
On the topic of the removal of fold_right
, I think we should keep it. fold_left
and fold_right
are pretty common combinators. I suspect the user discovering a fold
function would wonder which it is. Also, again regarding dynamic verification (i.e Ortac), using a combination of fold
(_left
) and rev
is not what we want for performance reasons. Finally, I think it will render specifications needing fold_right
a bit cumbersome and heavy. (Note that if you want to get the fold_right
signature that OCaml programmer's are used to, you'll have to flip the function argument -- and we don't have Fun.flip
).
The same line of argument applies to the removal of filter_map
.
ce369d0
to
4c425c0
Compare
I agree with most of your points, I normalized the formatting as you requested. I also made it so each function is abstract and re-added |
5169df2
to
751ea17
Compare
I have added the Coq proof, as well as fixing some small mistakes. There are two Coq files for the proof, the first is the In the future, once we integrate my changes into Gospel, we could have an extra test which checks if the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
I went through the Sequence
module again and made some inlined suggestions (feel free to squash them at the right place afterward).
I also have two more general remarks:
- Not all functions and predicates have an informal documentation
- I wonder about the order. Some axioms at the beginning of the module make use of functions that are defined later (
append_*
axioms mostly)
Since we have partial functions in Gospel, I am wondering what is the semantic of second order functions when one of the function argument is partial. For example, the
My guess would be that Do we need to document that? And if we do, how do we do it? |
135730b
to
db86738
Compare
Hello, I fixed all of the things you noted. I also updated the change In any case, I would say that if Gospel assumes functional |
Thanks! The more I review this PR, the more I think this is a very nice new standard library. I haven't reviewed the Coq/Rocq proof, as I am certainly not an expert. I have just a few remaining small remarks:
There is no problem :-), I was just wondering. In retrospect, this is something that should be documented in the language definition rather than in the standard library documentation. How do you want to proceed about the three modules at the end to be removed? You want to do it in this PR or another one? I believe this should be done before a release with the new standard library. |
I am going to remove as many deprecated definitions as I can in this PR. I am thinking I will do these changes in a separate commit, unless you prefer it get squashed into |
It makes sense to remove them in another commit as it will contain an update of the tests. Thanks for adding back |
I removed the deprecated modules and changed the tests accordingly, A few other changes I made:
|
Excellent: Thank you :-) I believe 41162f0 could have deserved its own PR. But is is ok. Once the conflict on the changelog has been resolved, this PR can be merged if you are ok with that. |
I thought of making it its own PR, but since this one is almost done, I figured why not. Besides the fact that the arithmetic operators don't have specifications, I believe that the standard library is in a pretty good state and can be added into Gospel. |
Here is my pull request for the updated standard library. The goals of
this update are to:
Give a precise specification to the defintions within the library so
that there is no ambiguity as to their meaning
Gear this library to the definition of mathematical and logical
formulae that will be used within specifications. This means removing
elements such as references and exceptions which do not make sense
in purely logical contexts
In order to achieve these two goals, we have removed or modified some
of the definitions within this library. I will now go over them and
justify them (note that some of these definitions are still in the
standard library but only so that the tests still pass. In the
future, these should be modified so as to not rely on these
definitions):
Removed Definitions
References
Self explanatory: it does not make sense to talk about references
within purely logical formulae.
Bitwise Operations
Although one could imagine a specification where one uses bitwise
operations, these operations are out of place in a mathematical
library. Additionally, these definitions are already present in the
OCaml standard library and it does not make sense to duplicate them
here. A better alternative would be to give those functions a gospel
specification and allow users to use them if necessary in their
specifications.
Operations on Pairs
Similar justification to bitwise operations.
Sequence Module
In the sequence module we remove the functions
filter_map
,fold_right
, and renamedfold_left
tofold
In the case offilter_map
and
fold_right
, these are just compositions of previously definedfunctions; in the case of the former
filter
andmap
, and in the caseof the later
fold
andrev
. The renaming offold_left
felt naturalsince there is only one
fold
function. I don't feel very stronglyabout these changes and if enough of a need arises, we could add them
again.
List Module
The entire
List
module was removed from the standard library. The mainreason is that the
list
type serves a similar purpose tosequence
within specifications and it feels unnatural to have two very similar
ways of reasoning over an ordered sequence of elements. Currently, to
reason over lists in Gospel specifications, we just use a coercion
that transforms them into
sequences
; in the future when we add someform of representation predicates to Gospel, we could have it so that
the logical model of the type
list
issequence
.Array Module
As i said with regards to references, it does not make sense to talk
about arrays in a logical context
Bag Module
The
occurrences
function has been renamed tomultiplicity
. This alsoimplied changing some of the tests.
The
is_empty
function has been removed since one could simple stateb = empty
as opposed tois_empty b
.The
choose
andchoose_opt
functions have also been removed. It isunclear why one would use these in a specification.
The
map
has also been removed. This is because it is very difficult todefine it in the case that the parameterized function is not
injective.
The
fold
function has also been removed. This is because it isimpossible to define this function without also defining a canonical
ordering of the elements within the bag.
The
_exists
andfor_all
predicates have also been removed as well asthe
partition
function. To be honest, I do not remember the reasonswhy.
The conversion function to a
sequence
has also been removed since thiswould also imply a canonical ordering. The conversion from a
sequence
has also been removed, but I think that might have been a mistake.
Set Module
The
compare
function has been removed, no idea what kind ofspecification one could give it or why one would use it in a
specification.
The remaining removed functions are similar to those from the Bag
module and therefore I don't think there is a need to explain them
again.
Order module
Since this module is about mathematical definitions it feels out of
place to define a class of valid ordering functions for OCaml
code. Although it makes sense to have this definition somewhere in
Gospel, we should place it somewhere else.
System Variables and Exceptions
Similar Reasoning as to references.
Added Definitions
I don't think anything that we have added merits in depth explanation:
mostly it was just defining all the functions we could and
axiomatizing the rest. The majority of these definitions have been
formalized and verified in Coq with a few exceptions these beings some
axioms regarding cardinality and a few recently added axioms regarding
subsequences.
Future Work
One glaring omission is the absence of axioms regarding arithmetic operations. These are absent since they are very cumbersome although fairly straight forward.
I would like have better notation for all of these Gospel data types:
notably it would be pleasant to have pretty notation for the
init
andmem
functions.Naturally, if these changes are accepted, the tests should be changed
so as to not rely on deprecated definitions. Personally, I think we
should leave them as is and tackle them once we have ways of talking
about ownership of OCaml values. This is because some of these
conflicts, notably with references and arrays, are due to the fact
that Gospel does not have a good way of talking about them in
specifications. I believe that once we have added some form of
representation predicates, that these tests can be rewritten quite
naturally.
Finally, at some point we should separate these modules into distinct
files. For now, since the standard library is still quite small, it is
still manageable, however, as we add more things to it, it can very
quickly become a big mess.