Using scopes, one can control which notations are available for parsing. But it looks like this does not affect printing: if I have two different notations that are defined in different scopes and both apply, Coq will choose the last one defined rather than use scoping information to determine which one to use:
Variable (tag foo : Type).
Declare Scope tagged_scope.
Delimit Scope tagged_scope with tagged.
Declare Scope untagged_scope.
Delimit Scope untagged_scope with untagged.
Class Cl (ta : tag) := cl : foo -> Type.
Notation "[ |-[ ta ] f ]" := (cl (ta := ta) f) : tagged_scope.
Notation "[ |- f ]" := (cl f) : untagged_scope.
Section Sec.
Context `{Cl}.
Open Scope tagged_scope.
(* printed as untagged *)
Goal forall f, [ |-[ta] f].
Abort.
End Sec.
Section Sec.
Context `{Cl}.
Open Scope untagged_scope.
(* if I reorder the notations, here this will print as tagged *)
Goal forall f, [|- f].
Abort.
End Sec.
Is there a way to locally control over which notation gets used for printing? Ideally, I would like to avoid having to resort to importing modules, because they would force me to define all notations together, while I want to define them in a progressive manner.
I guess a solution would be to defined the "untagged" notation as being parse-only, and always have the tagged variant printed. This adds visual clutter that I would preferably avoid when possible, though.
re "importing modules", you can encode splittable modules (and NES namespaces automates that in elpi), but the real issue is that printing notations are _sometimes_ used even when the module is _not_ imported but only required :-|
ah it's https://github.com/coq/coq/issues/14587
and closing scopes isn't meant to affect printing notations — we don't want to lose pretty-printing for 42%N
just because I never Open Scope N_scope.
:-|
Coq will choose the last one defined rather than use scoping information to determine which one to use:
so moving the notations into modules A
and B
should let you use Import A.
and Import B.
, and NES should enable splitting A
and B
. Let me find a link...
uh, I can't find better docs than https://github.com/LPCIC/coq-elpi/blob/v1.15.6/apps/NES/tests/test_NES.v, but that shows the key part:
(* name space creation *)
NES.Begin Foo.
Definition x := 3.
NES.End Foo.
Print Foo.x.
(* adding one name inside an existing name space *)
NES.Begin Foo.
Definition x2 := 4.
NES.End Foo.
Print Foo.x.
Print Foo.x2.
NES is a POC, I don't thing "Importing a name space" works, since "A" is morally "Rundom1.A" and "Random2.A", and importing both Random1 and Random2 gives you the impression that you get the ordered union of As, but Import A will import just the last one, if I'm not mistaken. CC @Cyril Cohen
Import A.
won't work indeed... but NES.Open A.
will
And for better or worse, NES "resolves" coq#14587: a namespace generates auxiliary modules and imports them, so notations are enabled for printing right away
Paolo Giarrusso said:
and closing scopes isn't meant to affect printing notations — we don't want to lose pretty-printing for
42%N
just because I neverOpen Scope N_scope.
:-|
I agree with that, but shouldn't scopes still inform the printer that it should prefer some notations over other?
But so for my usage, do you confirm that I either have to go with modules, or have only one set of printing notations (and the "untagged" version as parse-only if I really want that)?
Not certain you have to, but I don't know another way, maybe you should tag Hugo Herbelin. We use the "module-based shadowing" quite a bit...
Ok, let's try and summon @Hugo Herbelin!
Trying to use the stack of scope to print notations was tried once and reverted due to incompatibilities (see https://github.com/coq/coq/pull/8187 for a long story). The criterion to prefer more defined notations first seemed to have been a compromise (https://github.com/coq/coq/pull/12986). So, for instance, if your ta
could be associated to a specific constructor, then the more defined notation [ |-[ ta ] f ]
using this constructor would be used by default whenever possible.
An alternative would be to issue commands such as:
Disable Notation "[ |- f ]" (only printing).
Disable Notation (only printing) : untagged_scope.
Disable Notation := (cl _) (only printing) : untagged_scope.
etc., depending on the level of specificity you want to get.
Thanks for the backstory! I think these Disable Notation
will let me do what I am after :) I'll just have to wait for 8.18 to be out
oooh, those commands actually exist! Even in 8.17! https://coq.github.io/doc/v8.17/refman/coq-cmdindex.html
Last updated: Sep 23 2023 at 13:01 UTC