Directives can change built-in predicate properties
The following Prolog text does not throw any errors and changes the runtime behavior of predicate_property(true,X):
:- dynamic(true/0).
(btw, true/0 is still static, even though predicate_property/2 now reports it as dynamic; attempting to assert a new clause to it results in an error regardless)
Using a directive on a builtin in this way should result in an error when the text is interpreted or compiled.
This applies to the directives:
-
dynamic/1 -
multifile/1 -
discontiguous/1
I'm not sure whether it should apply to the directives:
-
meta_predicate/1 -
module/2(exporting a builtin) -
use_module/1(importing a builtin)
Expected: permission_error(modify, procedure, true/0)
permission_error(modify, static_procedure, true/0)
On closer inspection, it seems the predicate properties resolve differently depending on how true is qualified:
?- predicate_property(user:true,X).
X = built_in
; X = dynamic
; false.
?- predicate_property(builtins:true,X).
X = built_in
; false.
This gives an error as well:
:- dynamic(builtins:true/0).
error(permission_error(modify,not_declared_multifile_or_discontiguous,builtins:true/0),load/1).
Expected:
permission_error(modify, procedure, true/0)
Might be better to have it be:
permission_error(modify, builtin_procedure, true/0)
Or maybe even this, if we want to consider this just a special case of trying to change an (implicitly) imported procedure:
permission_error(modify, implicit, true/0)
It should be permission_error(modify, static_procedure, true/0) similar to asserta/1 8.9.1.4, 7.12.2 e, PermissionType.
This gives an error as well:
:- dynamic(builtins:true/0).
error(permission_error(modify,not_declared_multifile_or_discontiguous,builtins:true/0),load/1).
That is master, rebis-dev gives as Culprit: builtins:true(0)
It should be
permission_error(modify, static_procedure, true/0)similar toasserta/18.9.1.4, 7.12.2 e, PermissionType.
I disagree.
In every case, permission_error(_, static_procedure, _) is about trying to inspect or alter the clauses of a static procedure because this is incorrect by definition of a static procedure.
The reason I suggested permission_error(modify, builtin_procedure, true/0) instead is for uniformity if you try to use the multifile or meta_predicate directives. A static procedure may also be multifile, so it's misleading to say the reason for failure is that it is static.
The reason I suggested permission_error(modify, implicit, true/0) is by analogy with the module-aware redefinition of asserta/1 in ISO/IEC 13211-2 7.4.1.3 g[^1].
f) The predicate indicator
PredofHeadis that of a static procedure- permission_error(modify, static_procedure, Pred).g) The procedure identified byPredis imported or re-exported by the moduleDM- permission_error(modify, implicit, Pred).
[^1]: Even though Scryer does not conform to ISO Modules, it is nevertheless a useful design inspiration. Note specifically that in ISO Modules, builtins don't belong to any module. OTOH in Scryer, builtins module is always implicitly in the visible database.
@UWN, I'm unclear why the :-1:.
Why do you think the errors for runtime dynamic predicate modification should also apply to loader directives? (this criticism applies to my suggestions too! I don't know if a permission_error is appropriate at all)
Do you also think the same error should apply to :- module(foo, [false/0])? If not, which?
I disagree strongly both with your suggestions and your argumentation. You do find certain inconsistencies. And that is a good thing. However, you then use them to draw conclusions that I downvote, as I disagree. And as you have shown on the module discussion, it is impossible to discuss this with you.