Closed bclement-ocp closed 10 months ago
I think that's correct, i'll fix that.
That being said, after a bit more thinking, this is really weird, and maybe should not be done. Using reserved words as identifiers, even quoted, just seems prone to confusion, and doesn't seem to be supported in a consistent way by existing solvers.
For instance, Z3 supports (declare-const |forall| Int)
but CVC5 doesn't; on the other hand CVC5 supports (declare-const |_| Int)
while Z3 doesn't, and both support (declare-const |!| Int)
. All of these are part of the set of reserved words.
It is probably fine to take the lax interpretation of "Following Common Lisp’s conventions, enclosing
a simple symbol in vertical bars does not produce a new symbol." as implying that assert
and |assert|
are the same "pseudo-symbol" and hence neither is valid as a symbol.
It's not easy to determine indeed, but first let me state that for most things related to the spec, the behaviour of solvers is not really a good indication (sadly enough). Basically, the problem boils down to the following two choices:
(declare-fun |assert| () Bool)
(|assert| false)
So basically, this is the choice we have: exactly one of the two statements above should be legal (and the other not). I would say that for now my reading of the specification would make me go towards the first solution (i.e. quoting allows to use usually reserved names as symbol names), but I agree it's not really clear.
I think there is a third reading, which is the one I was going for: quoted reserved words behave as reserved words in contexts where a quoted symbol is allowed by the grammar.
(declare-fun |assert| () Bool)
is rejected, because (declare-fun <symbol> () Bool)
is allowed and the symbol is assert
, which is a reserved word;(|assert| false)
is accepted, because the syntax is (assert <term>)
, not (<symbol> <term>)
In fact there is a weird discrepancy in the way that the standard excludes reserved words versus symbols starting with @
or .
from being used. From a strict reading of the spec:
@
or .
are "reserved for solver use";So |assert|
is OK, even though assert
is a reserved word, because assert
is not a simple symbol, |assert|
is not "enclosing a simple symbol in vertical bars"; but |@assert|
is reserved, because @assert
is a simple symbol, and so |@assert|
and @assert
are the same symbol.
On the other hand, |@é|
is technically allowed, since it is not a "simple symbol starting with @
or .
" (and yet I believe it is rejected after #185 ).
Your understanding is probably the one that matches the (quite fuzzy) specification of the smtlib spec. That being said, I'd argue for a slightly different semantics for a few reasons.
So first, my proposition:
|assert|
would act as a symbol (and not a reserved word), so you can define/declare/let-bind it@
or a .
Now for a few reasons:
|@é|
and the like, here I'd argue for simplicity and predictability of the syntax, as well as separation of the syntax and typing/name resolving parts of the language: quoting is a syntax mechanism to overcome some difficulty related to the syntax of symbols/identifiers, as well as the usefullness of reserved word for parsing (which would make it extremely annoying/complex to try and support assert
as both a reserved word or a symbol depending on its position in the source). On the other hand symbols reserved for solver use is a typing/name resolution thing: the restriction is not enforced during parsing, and the rules that drives it are more closely related to name resolution, and name shadowing than, the syntax.That way quoting is only relevant in the parser, and the information of what was quoted disappears afterwards, and not used during typing, because it makes more sense for quoting to be a syntax solution to a syntax problem, and typing can then simply not care about the syntax.
Yeah, I also think that this is the most reasonable implementation.
That said, if quoted keywords are allowed, it would be really useful for Dolmen to provide quoting printers so that users don't have to manage the list of keywords on their own when printing models.
Yup, such functions will be part of the printing functionality of Dolmen (which I should really get to soon..).
My point is that even without the full printing functionality having only these functions would be very helpful, and probably easier to implement than the full printing functionality (but maybe not that much?).
Well, it's more that these functions solve one very particular problem, which is to ensure that what you print is likely to be parseable, however, it doesn't ensure that what is parsed is what you want (e.g. that you didn't accidentally shadow some variables or definitions).
True, but for my specific use case (which is model printing in Alt-Ergo), having just those functions should be enough :)
Hm.. right, I'll add those functions as soon as I have the time.
According to my reading of 3.2