Article View: comp.lang.prolog
Article #1142Re: Meta-programming question
From: Richard A. O'Keefe
Date: Fri, 31 Aug 1990 02:41
Date: Fri, 31 Aug 1990 02:41
96 lines
4397 bytes
4397 bytes
In article <199@qt.cs.utexas.edu>, bradley@cs.utexas.edu (Bradley L. Richards) writes:
> I want to locate a clause via unification with its
> head, and then be able to retrieve the clause *without binding any variables*.
> The goal here is to modify the clause and replace it, so it's essential that
> I avoid making unintended changes via bindings.
Sigh. This is why we wanted a Prolog standard...
It isn't perfectly clear what you don't want bound. If you are probing
for a clause with a pattern, and you are happy for that pattern to get
instantiated, but you want (a copy of) the original clause, do
head_clause_nobind(Head, Clause) :-
clause(Head, _, Ref),
instance(Ref, Clause).
in any Edinburgh-compatible Prolog. If you don't want the pattern to
be bound either, do
head_nobind_clause_nobind(Head, Clause) :-
findall(Clause, head_clause_nobind(Head,Clause), [Clause]).
/* There is a subtle detail here. This would work in DEC-10 Prolog, but
head_nobind_clause_nobind(Head, Clause) :-
findall(Ref, clause(Head, _, Ref), [Ref]),
instance(Ref, Clause).
would _not_ work in DEC-10 Prolog. C Prolog, Quintus Prolog, SICStus
Prolog, NU Prolog, and others would have no problem.
*/
> In Arity Prolog I can achieve most of this effect by accessing the clause
> using their database predicate "recorded," which returns both the clause
> (which I verify via unification) and a reference number I can use for later
> access. The catch is that any comparator predicates (e.g. N \== 2) are
> loused up in the returned clause. Arity tells me that they hadn't intended
> for users to access clauses with database predicates, so this isn't a
> supported feature.
I am rather surprised that 'recorded' can get at ordinary program clauses;
a large part of the reason for having 'recorded' in DEC-10 Prolog was to
make it _impossible_ to confuse database terms with clauses.
It's rather hard to suggest anything without an Arity manual.
Let's see what we might do.
head_nobind_clause_nobind(Head, Clause) :-
functor(Head, F, N),
functor(Skel, F, N),
clause(Skel, Body),
\+ \+ Skel = Head,
make_clause(Skel, Body, Clause).
make_clause(Head, true, Clause) :- !, Clause = Head.
make_clause(Head, Body, :-(Head,Body)).
This will do what I _think_ is wanted. It is, of course, rather slow.
May I respectfully suggest that trying to use the "raw" clause store
is almost always a bad idea? Suppose you are doing your meta-programming
and start tinkering with the append/3 predicate. What if your meta-program
uses append/3? You want to keep the levels separate.
I would be strongly inclined to keep the "object" clauses in their own
table. (I'd rather keep them in a term, but on a PC the 8086's addressing
limitations are such that that's likely to be hard.) For example, the
very simplest way of solving _this_ problem is, whenever you store an
"object" clause, instead of doing
assert((Head :- Body))
do
assert(object_clause(Head, Head, Body)).
What does that buy you? Why this:
head_clause_nobind(Goal, (Head :- Body)) :-
object_clause(Goal, Head, Body).
In fact, for meta-programming (as John Lloyd and others have pointed out)
it may be better to use a representation in which object clauses are ground.
You could then do
store_object_clause(Head, Body) :-
/* Head and Body are ground terms */
unnumbvervars(Head, Goal),
assert(object_clause(Goal, Head, Body)).
fetch_object_clause(Goal, Head, Body) :-
/* Goal may be instantiated; Head, Body come back ground */
object_clause(Goal, Head, Body).
Whether you use a ground representation or not, I strongly suggest keeping
the "object" clauses in their own table. Amongst other benefits, that way
you can be sure that assert won't rewrite the body of one of your clauses,
because it won't realise that it _is_ a clause body.
--
You can lie with statistics ... but not to a statistician.
Technical Details
Message-ID:
<3646@goanna.cs.rmit.oz.au>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!munnari.oz.au!goanna!okReferences:
<199@qt.cs.utexas.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!munnari.oz.au!goanna!ok From: ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) Newsgroups: comp.lang.prolog Subject: Re: Meta-programming question Message-ID: <3646@goanna.cs.rmit.oz.au> Date: 31 Aug 90 02:41:31 GMT References: <199@qt.cs.utexas.edu> Organization: Comp Sci, RMIT, Melbourne, Australia Lines: 96