Open jjtolton opened 2 hours ago
You can expand it for example to:
nullified :- false.
Or use for example the predicate name '$nullified'
as a more "internal" name that is less likely to conflict with existing predicate names.
Nullification works for me:
?- [user].
term_expansion(b, []).
a.
b.
c.
?- a.
true.
?- b.
error(existence_error(procedure,b/0),b/0).
?- c.
true.
?-
@hurufu: No, it has only replaced b
by []
(which currently we cannot call, but it works in rebis-dev
!).
You can see the issue with:
term_expansion(b, []). a. b. c. b.
yielding:
% Warning: overwriting []/0 because the clauses are discontiguous true.
@hurufu: No, it has only replaced
b
by[]
(which currently we cannot call, but it works inrebis-dev
!).You can see the issue with:
term_expansion(b, []). a. b. c. b. yielding:
% Warning: overwriting []/0 because the clauses are discontiguous true.
Wow, indeed. Silly me. I think it should count as a bug. Then yes, the only solution I see is currently to expand to known "bad" predicate, as you have proposed. Or even better to some undefined dynamic predicate, so it would fail faster.
@hurufu: I think the intuition is justified though, that an expansion of []
results in a vanishing definition, because the definition of the fact []
seems extremely unlikely to be intended.
A fact []
can still be written as []:-true.
Note that in SICStus, a single [].
is ignored. And a list of terms is just handled as a sequence of such terms.
| ?- [user].
% compiling user...
| [f(1),f(2)].
|
% compiled user in module user, 44 msec 516288 bytes
yes
| ?- f(X).
X = 1 ? ;
X = 2 ? ;
no
In SWI, however
Welcome to SWI-Prolog (threaded, 64 bits, version 9.3.13)
...
?- [user].
|: [f(1),f(2)].
|: ^D% user://1 compiled 0.00 sec, 4 clauses
true.
?- f(X).
X = 1 ;
X = 2 ;
X = 1, unexpected ;
X = 2, unexpected.
tl;dr
There should be some way to nullify terms in term expansion without needing to result to
(:- module(random_name, [])
, probably by doinguser:term_expansion(<pattern>, []).
Overview
There is no easy way to nullify terms using term expansion, and the same is probably true for goal expansion though I haven't tested it yet.
By nullify I mean "expand to zero terms". So to nullify term
(b)
from the following:We would expect the nullification of
(b)
to result in:Motivation
I like to add the following to my scripts these days:
The way I don't get the following warning in commented queries There should be some way to nullify terms in term expansion without needing to result to
(:- module(random_name, [])
, probably by doinguser:term_expansion(<pattern>, []).
:
You can also use the same technique to make custom
:-
directives:(this technique is necessary because
:- initialization(something)
comes after _termexpansion, so if you want to used initialized state, you must initialize the state in the term expansion lifecycle phase rather than then initilization lifecycle phase)Explanation of Workaround
Note the hack: (:- module(a, []). That's because this is the only way I know of to NULLIFY a term, equivalent to a comment macro in lisp:
Exploration of Current Behavior
These are the following techniques you would probably expect to work in Prolog:
Doesn't work, the term will remain unchanged and then eventually called as is resulting in the same warning. (Note: this is expected, I think. I don't think
false
should nullify the term).The following should probably splice or expand into 0 terms in place of the current term:
however it results in the following warnings:
which indicate to me that
[]
is being treated as a fact.You can get the same warning by doing:
Expectation vs Reality
The net result of this is that you can't make a side-effecting user-defined directive with the
:-
operator because you get a domain error:results in
unless you do something like:
You can't simply do
because that will still result in an unchanged
(:- womp)
which results inExpectation
There should be some way to nullify terms in term expansion without needing to result to
(:- module(random_name, [])
, probably by doinguser:term_expansion(<pattern>, []).