Hello,

I am fairly new to this and sorry if it has some obvious solution I did not find. Is there a way to know if a binary infix notation is left or right associative ?

I only know of `Locate "+".`

for instance, but it does not display this information (priority is also hidden).

I also don't know. As a workaround, you can temporarily `Set Printing Parentheses.`

to find out.

Try using `Print Grammar constr.`

(see here for details https://coq.inria.fr/refman/user-extensions/syntax-extensions.html)

I

My hack for finding the priority is to (try to) redefine the notation at some random level. For example:

```
Notation "a + b" := (a - b) (at level 0).
```

Since "+" is not actually defined at level 0, Coq complains with a very informative message:

```
Error: Notation "_ + _" is already defined at level 50 with arguments constr
at level 50, constr at next level while it is now required to be at level 0
with arguments constr at next level, constr at next level.
```

you should see something like this:

```
| "95" RIGHTA
[ SELF; "<->"; NEXT ]
```

where the number (`95`

here) is the precedence (lower will be parsed first), then `RIGHTA`

tells you it's rigth associative and then you see the notation (in this case `<-->`

).

Actually we could do much better, unless I'm missing something, we could add some kind of `Print Notation`

command; that kind of functionality is exposed in serapi, so users can do:

```
(Query () (Unparsing "_ + _"))
(Answer 0 Ack)
(Answer 0
(ObjList
((CoqUnparsing
(((UnpBox (PpHOVB 0)
((() (UnpMetaVar (LevelLe 50) (Left))) (() (UnpTerminal " +"))
(() (UnpCut (PpBrk 1 0))) (() (UnpMetaVar (LevelLt 50) (Right))))))
50)
()
(((notgram_level (InConstrEntry 50 ((LevelLe 50) (LevelLt 50))))
(notgram_assoc (LeftA)) (notgram_notation (InConstrEntry "_ + _"))
(notgram_prods
(((GramConstrNonTerminal
(ETProdConstr InConstrEntry
((NumLevel 50) (BorderProd Left (LeftA))))
((Id x)))
(GramConstrTerminal (PKEYWORD +))
(GramConstrNonTerminal
(ETProdConstr InConstrEntry
((NumLevel 50) (BorderProd Right (LeftA))))
((Id y))))))
(notgram_typs
((ETConstr InConstrEntry () ((NumLevel 50) (BorderProd Left (LeftA))))
(ETConstr InConstrEntry ()
((NumLevel 50) (BorderProd Right (LeftA))))))))))))
```

you can see the full info in the several records. So maybe indeed worth opening a bug to put this code into Coq.

https://github.com/coq/coq/issues/14907

Thanks @Ana de Almeida Borges

There is `Print Grammar constr.`

which prints the current grammar of Gallina terms.

See https://coq.inria.fr/refman/user-extensions/syntax-extensions.html#coq:cmd.Print-Grammar.

@Pierre Rousselin we ended up implementing `Print Notation`

, so from Coq 8.16 on you can just use it to find these things out!

Great ! Thanks a lot !

Last updated: Oct 01 2023 at 18:01 UTC