Some built-in predicates not callable
It seems predicate_property can resolve some predicates even though they are not executable as goals.
Regardless of whether or not these predicates are visible, I think predicate_property/2 and clause/2 are supposed to resolve a term in the same way as executing it as a goal.
?- predicate_property('$halt'(X), B).
B = built_in
; false.
?- '$halt'(X).
error(existence_error(procedure,'$halt'/1),'$halt'/1).
?- clause('$halt'(_),X).
error(permission_error(access,private_procedure,'$halt'/1),clause/2).
I'm not sure the status of so-called "system predicates" whose names start with $ - this needs to be documented.
- If they are built-in predicates, they should be visible everywhere according to IEC 13211-2.
- If they are not,
predicate_propertyshould have a documented value to reflect such predicates which are neither "built-in" nor "user-defined".
For some reason $ predicates can't be called from the toplevel, but they work fine if you use them in a file. This seems like a limitation of call/N, which is used in the implementation of the toplevel:
$ cat a.pl
a :- '$halt'(0).
b :- call('$halt'(0)).
$ scryer-prolog -f a.pl -g a
$ scryer-prolog -f a.pl -g b
b causes: error(existence_error(procedure,$halt/1),$halt/1)
?-
Another example:
?- [user].
a :- '$fail'.
b :- call('$fail').
?- a.
false.
?- b.
error(existence_error(procedure,'$fail'/0),'$fail'/0).
Related: https://github.com/mthom/scryer-prolog/issues/438
Please note that the top level is out of scope of the standard:
3.185 top level: A process whereby a Prolog processor repeatedly inputs and executes * queries. NOTE - This part of ISO/IEC 13211 does not define or require a processor to support the concept of top level.
For some reason
$predicates can't be called from the toplevel, but they work fine if you use them in a file.
Please note that the top level is out of scope of the standard
Good catch! I definitely assumed that submitting a goal through the top level versus through a file would not affect the outcome here.
I do think this falls under the standard though. Even if the top-level need not exist, the spec does specify how the processor should execute a goal once prepared.
7.7.3 Initialization The method by which a user delivers a goal to the Prolog processor shall be implementation defined.
Predicates names starting with $ are often internal predicates. In some systems (originally DEC10, YAP) all1 names starting with $ are "interned". Thus only references prior to that internalization work. I was never sure how this is seen in Scryer.
1 And then, there are names like '$VAR'/1 which originally were interned in DEC10, but later on were made visible to user code.