-
Notifications
You must be signed in to change notification settings - Fork 234
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
Forbidding injectivity of inductive types with parameters that are too large #1649
Conversation
Left some minor remarks, here a few higher-level ones. First, note that this now fails let isMkInj (x:_) (w:i x) : Lemma (w == Mkinj #x) = () I believe since Also note some types are not getting injectivity due to how universes are resolved. This one from type monoid_morphism (#a #b:Type) (f:a -> b) (ma:monoid a) (mb:monoid b) =
| MonoidMorphism :
unit:squash (monoid_morphism_unit_lemma f ma mb) ->
mult:squash (monoid_morphism_mult_lemma f ma mb) ->
monoid_morphism f ma mb It can be fixed like this type monoid_morphism (#a : Type u#aa) (#b : Type u#bb) (f:a -> b) (ma:monoid a) (mb:monoid b) : Type u#(max aa bb) = Seems to be the only one in Otherwise looks good to me, the universe check does seem sound. I would also rebase the PR so we have a cleaner history. I could do that if you want. |
Thanks for the comments, Guido. FWIW, I don't see the "minor remarks" you refer to. I'm still a bit unsatisfied with the restriction imposed by this patch. It's rather specific in that it excludes injectivity of type formers when they contain function-typed parameters with domain in universes that are too large. That excludes this particular paradox, which is good, and so I'm in favor of this being merged. OTOH, if the check is really to be justified on cardinality grounds, then a type with any parameter that is in a universe too large (not just those with function-typed parameters with too-large domains) should not be injective. But, that doesn't seem to be feasible at all, since it would exclude many simple parameterized inductive types. I'm inclined to merge this patch now, so that we forbid at least the paradox we know about. |
Also, not sure about the rebasing. We've generally not being doing that ... so why should this PR require it? |
let _, k = U.arrow_formals k in //don't care about indices here | ||
let tps, env_tps, _, us = TcTerm.tc_binders env tps in | ||
let u_k = | ||
match (SS.compress k).n with |
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.
Could we call env.universe_of
here?
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.
Not really, that would compute one universe too high.
In this case, we have, for instance, type t : Type u#0 = ...
where k = Type u#0
and we want u_k
to be u#0
not its successor.
I agree that this code is more syntactic than ideal. But, fwiw, the typechecking rules for inductices in TcInductive really enforce that the result type of an inductive is a Tm_type or eqtype.
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.
True, sorry, I meant TcTerm.level_of_type
| _ -> failwith (BU.format1 "Impossible: Type of inductive is %s" (Print.term_to_string k)) | ||
in | ||
//BU.print2 "Universe of tycon: %s : %s\n" (Ident.string_of_lid t) (Print.univ_to_string u_k); | ||
let rec universe_leq u v = |
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.
Maybe this function should live somewhere else, such as Syntax.Util
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.
I didn't want to put this in Syntax.Util since I didn't want it to be used outside of a context (e.g., in the typechecker) where universe unification variables may still be around. This boolean function may give the wrong result when called on universe terms with U_unif terms. The proper way of checking of enforcing universe inequalities in the typechecker would be to call FStar.TypeChecker.Rel to register and solve universe inequality constraints.
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.
Note, within the SMT encoding, we really ought to not have U_unif anymore ... I suppose I could assert that here.
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.
OTOH, when this function returns false, the is_injective flag is false ... i.e., erring conservatively.
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.
I indeed interpreted as a conservative leq, where returning false means "I don't know". It might be useful somewhere else, but we could factor it out when the need arises.
Sorry, I missed to hit "submit" on the review again. I also think we should merge this for the time being, even if we're not so certain about it. I'm fine with not rebasing. I only like it to have a cleaner git history to bisect or find out how something evolved. |
See the discussion in issue #349