10

I'm quite new at Coq and trying to develop a framework based on my research. My work is quite definition-heavy and I'm having trouble encoding it because of how Coq seems to treat sets.

There are Type and Set, which they call 'sorts', and I can use them to define a new set:

Variable X: Type.

And then there's a library encoding (sub)sets as 'Ensembles', which are functions from some Type to a Prop. In other words, they are predicates on a Type:

Variable Y: Ensemble X.

Ensembles feel more like proper mathematical sets. Plus, they are built upon by many other libraries. I've tried focussing on them: defining one universal set U: Set, and then limiting myself to (sub)Ensembles on U. But no. Ensembles cannot be used as types for other variables, nor to define new subsets:

Variable y: Y.           (* Error *)
Variable Z: Ensemble Y.  (* Error *)

Now, I know there are several ways to get around that. The question "Subset parameter" offers two. Both use coercions. The first sticks to Sets. The second essentially uses Ensembles (though not by name). But both require quite some machinery to accomplish something so simple.

Question: What is the recommended way of consistently (and elegantly) handling sets?

Example: Here's an example of what I want to do: Assume a set DD. Define a pair dm = (D, <) where D is a finite subset of DD and < is a strict partial order on D.

I'm sure that with enough tinkering with coercions or other structures, I could accomplish it; but not in a particularly readable way; and without a good intuition of how to manipulate the structure further. For example, the following type-checks:

Record OrderedSet {DD: Set} : Type := {
  D     : (Ensemble DD);
  order : (relation {d | In _ D d});

  is_finite         : (Finite _ D);
  is_strict_partial : (is_strict_partial_order order)
}.

But I'm not so sure it's what I want; and it certainly doesn't look very pretty. Note that I'm going backwards and forwards between Set and Ensemble in a seemingly arbitrary way.

There are plenty of libraries out there which use Ensembles, so there must be a nice way to treat them, but those libraries don't seem to be documented very well (or... at all).

Update: To complicate matters further, there appear to be a number of other set implementations too, like MSets. This one seems to be completely separate and incompatible with Ensemble. It also uses bool rather than Prop for some reason. There is also FSets, but it appears to be an outdated version of MSets.

Community
  • 1
  • 1
mhelvens
  • 4,225
  • 4
  • 31
  • 55

1 Answers1

4

It's been (literally) years since I used Coq, but let me try to help.

I think mathematically speaking U: Set is like saying U is an universe of elements and Ensemble U would then mean a set of elements from that universe. So for generic notions and definitions you will almost certainly use Set and Ensemble is one possible way about reasoning about subsets of elements.

I'd suggest that you take a look at great work by Matthieu Sozeau who introduced type classes to Coq, a very useful feature based on Haskell's type classes. In particular in the standard library you will find a class-based definition of a PartialOrder that you mention in your question.

Another reference would be the CoLoR library formalizing notions needed to prove termination of term rewriting. It has a fairly large set of generic purpose definitions on orders and what-not.

akoprowski
  • 3,297
  • 1
  • 18
  • 26
  • Hi Adam! I share your general view on `Set` vs. `Ensemble`. But this doesn't give me a good way to (for example) use an Ensemble as a type for a new variable which then behaves as a subset. Well, not without a coercion. Perhaps there is no way around that? – mhelvens Jun 02 '13 at 09:16
  • You mean for the subset part in your *Question*? Well, your order is partial anyway, so is there anything preventing you from defining your order on the whole universe _DD_ instead? I think that would be a more customary way of doing it, unless there are some additional constraints you didn't mention? – akoprowski Jun 02 '13 at 19:56
  • Well, all the parts of my question, actually. The example was just that: an example. I'd like a way to consistently switch between (sub)sets and (sub)types without having to figure it out on a case-by-case basis. --- But about that partial order: it's a manually specified finite partial order (to go with the finite set). If I type it as an order on DD it might order elements outside the set *D*. I'm not sure if that would mess with any proofs in the future... but it's not particularly elegant. – mhelvens Jun 02 '13 at 20:44
  • 1
    Generic comment: in Coq the representation that you chose can make a huge impact on your proofs. It's also important what's your goal in the end (for instance if you want to eventually extract some code from your proofs this is an important consideration). So it's hard to give generic advice, but if I were to do it I'd say: use `Set`s and relations (two very fundamental notions in Coq) as much as possible. Also I wonder how important is the assumption that the sets are finite for you; if possible, it's not uncommon for generalized theories to be easier to formalize. – akoprowski Jun 03 '13 at 04:42
  • 1
    It's not my intention to generate code from my proofs. (As of yet I'm still working within constructive logic, but I might switch to classical if it ever becomes convenient.) --- If a `relation` (`S -> S -> Prop`) is a very fundamental notion in Coq then, surely, so is an `Ensemble` (`S -> Prop`). Anyway, it seems like all those Ensemble-based libraries are there for a reason. I just wish I had a good example of their use. – mhelvens Jun 03 '13 at 12:16
  • Yes, I'm not saying `Ensemble` is a very complex notion but it does introduce extra layer of complexity when you consider `relation S` with `U: Set; S: Ensemble U` VS `S: Set`. In any case, if at some point you have any concrete problem I can try to help. – akoprowski Jun 04 '13 at 02:36
  • In fact, `relation` can't even take an `Ensemble`. :-) But say I have many sets of elements that I routinely compare with each other. If all of them are `Set`s, that's pretty darn hard with all of them being disjunct by definition. I'd have to define and use a complex set of conversions. Anyway, I've decided to go with your original suggestion: create a universe using a `Set` and afterwards switch to all `Ensemble`s. It's working OK for now. Thanks! – mhelvens Jun 05 '13 at 08:00