How to kick yourself out of SWI-Prolog in 5 seconds

691 views
Skip to first unread message

Jan Burse

unread,
May 31, 2017, 7:38:54 PM5/31/17
to SWI-Prolog
Dear All,

This is a little beauty:

?- [user].

[_] :- foo.

|:

true.


2 ?- [user].

ERROR: '[|]'/2: Undefined procedure: foo/0

Exception: (8) foo ? abort

% Execution Aborted


What I wonder, why I dont get an error message when I overwrite '[|]'/2 ?

Interestingly when I overwrite other built-ins, like for example write/1
I get an error message:

?- [user].

write(_) :- foo.


ERROR: user://1:9:

No permission to modify static procedure `write/1'


But this is only because it is a foreign predicate. For non-foreign predicates

overwriting works unwarned:

append(_,_,_) :- foo.

|:

true.


2 ?- append(x,y,z).

ERROR: append/3: Undefined procedure: foo/0

Exception: (8) foo ? creep


Reason why I ask this, I see a lot of strange Prolog code recently:
https://stackoverflow.com/a/44223395/502187

Interestingly the case of '[|]'/2 is even more contrieved,
since it seems to belong to a module system:

?- listing('[|]'/_).

:- meta_predicate[:|+].


system:[A] :- !,

consult(A).

system:[A:B|C] :-

consult(A:[B|C]).


Whats the sickness and what is the cure?


Bye


P.S.: Here is what I did in Jekejeke, if a predicate isn't multifile

from the beginning, there is no chance at all to redefine a non-

module predicate in a non-module text:


?- [user].
[_] :- foo.
Error: Can't redefine predicate '.'/2, not marked multfile.

You can redefined a non-module predicate in a module text.

And you can redefined a module predicate in a non-module text.

Here is an example of the later:


?- [user].
member(_,_) :- foo.
Warning: Overriding predicate member/2, declare accordingly.


As can be seen, one gets a warning. Which one can disable for

the given predicate if one does an override directive first:


:- override member/2.
member(_,_) :- bar.


Jan Burse

unread,
May 31, 2017, 7:41:37 PM5/31/17
to SWI-Prolog
Corr.: before the member thingy, I did:

?- use_module(library(basic/lists)).

Since not like in SWI, things like append etc are not preloaded.

Jan Wielemaker

unread,
Jun 1, 2017, 4:47:11 AM6/1/17
to Jan Burse, SWI-Prolog
There is no sickness. All system predicates are defined in the module
`system`. This module acts as a default module for `user`. Normal user
modules inherit from `user`, system libraries from `system`. You can
redefine anything anywhere, except for ISO predicates (predicates with
the property `iso`).

You do have to redefine before use though. Once called, the definition
is materialized in the target module and a subsequent attempt to
redefine it will raise a permission error on a static predicate (unless
the predicate is not static of course).

SWI-Prolog is first of all intended to be flexible. Using the low-level
module interface you can get a long way redefining just about anything.
SWI-Prolog is not intended to actually deny you to do things. There are
tools to find redefined system predicates, cross-module calls to private
predicates, etc.

Cheers --- Jan


>
>
> Bye
>
>
> P.S.: Here is what I did in Jekejeke, if a predicate isn't multifile
>
> from the beginning, there is no chance at all to redefine a non-
>
> module predicate in a non-module text:
>
>
> ?- [user].
> [_] :- foo.
> Error: Can't redefine predicate '.'/2, not marked multfile.
>
> You can redefined a non-module predicate in a module text.
>
> And you can redefined a module predicate in a non-module text.
>
> Here is an example of the later:
>
>
> ?- [user].
> member(_,_) :- foo.
> Warning: Overriding predicate member/2, declare accordingly.
>
>
> As can be seen, one gets a warning. Which one can disable for
>
> the given predicate if one does an override directive first:
>
>
> :- override member/2.
> member(_,_) :- bar.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "SWI-Prolog" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to swi-prolog+...@googlegroups.com
> <mailto:swi-prolog+...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/swi-prolog.
> For more options, visit https://groups.google.com/d/optout.

Jan Burse

unread,
Jun 1, 2017, 5:00:28 AM6/1/17
to SWI-Prolog, burs...@gmail.com
IHi,

n a sandbox you restrict what can be called and what cannot
be called. But may restrictions should go also in the direction
what can be redefined and what cannot.

For example in SWISH I get for the code:

[_] :- foo.

A red marker in front of the clause which says "head_built_in".
And when I run the query, it is obviously redefined, despite
the red marker:

?- [user].
procedure `foo' does not exist
Reachable from:
	  [A|B]
	  swish_trace:swish_call([user])
	  '$swish wrapper'([user],A)

If I hoover over the query it still says "[/2 Read (compile) a
Prolog source file", so I guess there is a certain assumption
of immutability, but not completely realized by the system.

Bye

Jan Wielemaker

unread,
Jun 1, 2017, 5:27:21 AM6/1/17
to Jan Burse, SWI-Prolog
On 01/06/17 11:00, Jan Burse wrote:
> IHi,
>
> n a sandbox you restrict what can be called and what cannot
> be called. But may restrictions should go also in the direction
> what can be redefined and what cannot.
>
> For example in SWISH I get for the code:
>
> [_] :- foo.
>
> A red marker in front of the clause which says "head_built_in".
> And when I run the query, it is obviously redefined, despite
> the red marker:
>
> ?- [user].
>
> procedure `foo' does not exist
> Reachable from:
> [A|B]
> swish_trace:swish_call([user])
> '$swish wrapper'([user],A)
>
> If I hoover over the query it still says "[/2 Read (compile) a
> Prolog source file", so I guess there is a certain assumption
> of immutability, but not completely realized by the system.

There is nothing unsafe happening, so I see little reason to enforce
that in SWISH. The sandbox simply loads the program, while it ensures
you do not add clauses to other modules than the temporary module
assigned to the Pengine. Next it examines the goal and computes the
reachable call tree. If all (typically foreign) predicates in this tree
are flagged as safe and existing the goal may proceed.

Cheers --- Jan

Jan Burse

unread,
Jun 1, 2017, 8:08:19 AM6/1/17
to SWI-Prolog, burs...@gmail.com
I never used the word unsafe. I never discussed calling of predicates,
only definition of predicates. What do you mean by unsafe?
I mean unintended from a paedagogical viewpoint. Like consisteny
of user interface messages etc..

Basically I am voting for two modes: Novice and expert, somehow
it should not be possible for a common user to override too much
and get lost.

Interestingly such two modes can be implemented by directives.
Namely the idea is very simple:
- Novice: The novice sees a warning, doesn't know how to
      disable it, so will adopt his behaviour
- Expert: He is more aware about what he is doing, when
      he overrules something, this will be consciously done and
      expressed in the extra directive

We have already such things in Prolog. The many exception
and errors, that a predicate doesn't fail simply but rather yields
an exception. Further like the style checks, etc..

Safety is term with a slightly different reach. Its typically
concerned with ACL to resources, like what Anny recently
asked, can we do RCP from within a pengine,

the concept is well known from Java Virtual Machines
in the form of SecurityManagers. But it doesn't deal so
much with the language itself, especially the means to
define something, rather bla bla now I am getting bored.

Anyway you get the idea! Its not about calling something
but about defining something.

For example safety could go step further not only
Reply all
Reply to author
Forward
0 new messages