if I assert a new clause, for example:
assert(p(X)).
e subsequently retract that clause:
retract(p(Y)).
the tho variable have differente interal number (i.e. _244 the first
time, _260 the 2nd).
I would tho write predicates "myassert" and "myretract" to keep memory
of the internal number.
In the example I would Y have _244 internal number.
The question is: how can I reference the internal number of the
variables?
ps. I'm using SWI-prolog.
Thanks for all the answers
> The question is: how can I reference the internal number of the
> variables?
What problem are you trying to solve?
Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
"Normally" the actual name of a logical variable is not important -- hence
the freedom of assert/clause/&friends to rename them (provided they
do it consistently) as they see fit. If you wish to "read" the variable name
you'll have to do something ugly like writing (or displaying) a term out to a
string or (brrrrr!) file and scan it back in.
But if your assignment :) says something about maintaining your own
variable-naming conventions you could simply massage each term
before trying to assert/retract/clause it.
In SWI and some others there's numbervars/4 (a slight generalisation
of numbervars/3 from prehistory) that may come in handy for
any pre-assert mangling.
Using for example the clause/2 predicate (i.e for refereeing auxiliary
predicate) give back variable with new internal number...
this is the most recent attempt, I did:
myassert(P):- assert(P),
functor(P,Functor,NumParam),
P =..[Functor|Param],
assert(param-Functor-NumParam:-p-Param),
write(Param).
myretract(P):- functor(P,Functor,NumParam),
P =..[Functor,Param],
clause(param-Functor-NumParam,OldParam),
write(OldParam),
unifica(OldParam,Param),
retract(P).
unifica([H1],[H2]):- H1 = H2,
!.
unifica([H|T1],[H|T2]):- unifica(T1,T2).
[The "internal number" of a variable is not even constant: when garbage
collection occurs, most variables get a new internal number]
The best you can get is aliasing. If you want something else, please
describe it clearly.
If assert doesn't do what you want, try one of the setval predicates:
see the manual.
> I would refer exactly to the same variable. I tried to use auxiliary
> predicates to store variable name, lists, and other tricks, but the
> "problem" is in the unification algorithm.
*WHY* you want to do this? what problem are you trying to solve?
> Using for example the clause/2 predicate (i.e for refereeing auxiliary
> predicate) give back variable with new internal number...
If you assert a clause, and then retract it, you get new (=different) variables.
> this is the most recent attempt, I did:
doesn't have much sense.
P.
--
> [The "internal number" of a variable is not even constant: when garbage
> collection occurs, most variables get a new internal number]
>
> The best you can get is aliasing. If you want something else, please
> describe it clearly.
>
> If assert doesn't do what you want, try one of the setval predicates:
> see the manual.
Ok, thanks for the answer. If I don't have missunderstood, it is
impossible to have the same internal number every moment because of the
garbage collector...
What you seem to me to be asking for
is (or is equivalent to) a way to prevent
the Prolog Inference Engine (PIE)
from renaming rule variables.
The PIE has to rename all the variabes
in a rule each time it "visits" the rule in the course of looking for
answers to the current actual query, to ensure that no variable
in the rule logically coincides with any variable in the current actual
query.
This is true no matter if the rule was keyed in, consulted, asserted --
or if you are working with paper and pencil.
For example, suppose that, unbeknownst to you, I (the programmer)
happen to write the following rule:
p(A,T) :- q(A,T),r(B,T).
and you (the user) happen to pose the following query:
?- p(A,B).
If the PIE simply unified your query as written with the head of my
rule as written, without renaming any variables, it would make the
following
substitutions (mappings of *rule* variables):
p(B,C)
p(A,T) :- q(A,T),r(B,T)
-------------------------
{ A -> B, T -> C }
and the apparent new current actual query would be
q(B,C),r(B,C)
Otoh, if the PIE renamed the variables in the rule
before it did the substitutions, so that, say, the rule now reads
p(_V1,_V2) :- q(_V1,_V2),r(_V3,_V2)
it would make the following substitutions:
p(B,C)
p(_V1,_V2) :- q(_V1,_V2),r(_V3,_V2)
-----------------------------------
{ _V1 -> B, _V2 -> C }
and the new current actual query would be
q(B,C),r(_V3,C)
These are different results.
For example, let the data be
q(1,2).
r(3,2).
Then
q(B,C),r(B,C)
cannot be satisfied but
q(B,C),r(_V3,C)
succeeds if B=1, C=2, and _V3=3.
Now to your question.
Suppose the effect of the command
:- assert(p(X)).
were to create the rule
p(_244).
By what has been said above,
if you were now to issue the (actual) query
?- p(Y).
the first thing the PIE would do, preparatory to performing
the inference step, would be to rename the variables in this rule,
which now reads
p(_V1).
(say) so the inference step actually performed by the PIE would be
p(Y)
p(_V1).
--------
{} (set of bindngs is nil)
--------
_V1 -> Y
What matters here is not the '_V1' or the '_244'. What matters
is that it must be *impossible* for any of the variables in any rule
to clash with any of the variables in the currrent actual query --
again, no matter if the rule as asserted, consulted, or typed
in directly from the keyboard.
I suppose one could argue that if, as is the case here,
a particular rule variable does not actually have to be renamed
then it should not be renamed. I somehow doubt that
is what you are after, but if it is, implementing it would mean that
instead of
*automatically* renaming all the variables in every rule every time the
rule is consulted,
by applying a uniform method known in advance to guarantee the
impossibility of clashes,
the PIE would have to check each rule variable first and rename it only
if it actually occurred
in the current actual query -- with a corresponding cost i.t.o. performance.
--
billh