-
Notifications
You must be signed in to change notification settings - Fork 235
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
Polarities: subtyping for datatypes #65
Comments
This is not a bug. The type on the left is just We do not have subtyping on the indexes of an inductive type. We cannot add it unless we enhance the type system with a notion of polarities for type indices. You can, however, write a total coercion of the following type and use it to massage your type as needed.
Once we add support for ghost code, we should be able to erase uses of coercions like forget in generated code. |
Was thinking with @victor-dumitrescu the other day that polarities can be seen as a form of relational refinements. For instance, a positive type constructor like
where |
#593 has some good examples where polarities are really needed. |
Was discussing with @alejandroag the other day that internalizing subtyping (or any other judgment) is tricky, since the logical encoding is sound but incomplete. It seems that for the negative positions in a formula (like |
@aseemr Wondering whether we will also get this from your positivity check for inductives. |
@kyoDralliam has discovered a counterexample/paradox in the literature showing that enabling subtyping for datatypes would currently be unsound. He knows about this for a while, still it would be good to write this all down somewhere (e.g. here). From what I understand, a potential solution for this would be to remove type arguments to datatype constructors. |
@catalin-hritcu @kyoDralliam Is that the counterexample from Luo's note about Russell-style universes (http://www.cs.rhul.ac.uk/~zhaohui/universes.pdf)? |
It's that same counterexample. Here's is what it looks like for F* + subtyping for pairs. type pair a b : Type = | MkPair : a -> b -> pair a b
let elim (a b : Type) (c : pair a b -> Type) (f: (x:a -> y:b -> c (MkPair #a #b x y))) (p: pair a b) : c p
= match p with | MkPair x y -> f x y
let subject_reduction_failure (x y:nat) (c:pair int int -> Type)
(f : (x:int -> y:int -> c (MkPair #int #int x y)))
: c (MkPair #nat #nat x y <: pair int int (* we don't have this now *)) =
elim int int c f (MkPair #nat #nat x y <: pair int int (* we don't have this now *))
(* This returns -1 at type nat *)
let unsound () : nat =
subject_reduction_failure 1 2 (function (MkPair #a #b x y) -> a) (fun x y -> -1) this is well typed because |
The current fix proposal discussed with @theolaurent and @kyoDralliam is to prevent matching inductive parameters. In Kenji's counterexample this will make it impossible to write |
Discussed this again with @kyoDralliam and @mtzguido, and the main challenge for adding datatype subtyping is that now constraints such as |
I'm now getting errors on
It seems a recent change from July by @nikswamy : 8939c3e#diff-9a12b72662f95654a4c5ab46f41257b3R99 |
@catalin-hritcu Confused by your last remark. Projecting the parameters of a datatype is exactly what we want to prevent. Why do you want to write it? |
@nikswamy Sorry if this was unclear. Completely preventing matches on inductive parameters is indeed what we need for fixing this issue. And the question is whether your change completely prevents such matches already. |
Status update on this issue:
|
Addressing this issue requires more research. Closing as a wontfix until then. |
Just for the record, wanted to mention that @kyoDralliam and @theolaurent are doing some of that research. For instance, the French readers can see this: https://kenji.maillard.blue/Writings/mettons-de-l-ordre-dans-cic-171220.pdf |
... and a more recent extended abstract in English: Noninvasive Polarized Subtyping for Inductive Types. Théo Laurent and Kenji Maillard. TYPES 2022. |
…in compiler sources
Let me mention that there is a now paper about the research above that will appear at ESOP'24: |
(x:int{x>1} * y:int{y>1})
is not a subtype of(int * int)
The text was updated successfully, but these errors were encountered: