Subject: Re: [SWIPL] generating dynamic rules?

From: "Richard A. O'Keefe" <[email-masked]>
Date: Thu, 8 Mar 2001 12:42:49 +1300 (NZDT)

"Dietmar Harlos" <[email-masked]> wrote:
	I have the following problem with SWI-Prolog.  I have to
	generate a dynamic rule at runtime, but the variables don't
	match.  Please see this short example:
	
	    knot(1, fetch(Variable)).
	    knot(2, write(Variable)).

	    dynrule :-
		knot(1, Rule1),
		knot(2, Rule2),
		assert(( testme :- Rule1, Rule2 )),
		listing(testme),
		testme.

	    fetch(A) :-
		A = 4.

	The output at the prolog prompt is as follows:
	
	?- dynrule.
	
	testme :-
	        fetch(A),
	        write(B).
	_L114
	
	Yes

A *fundamental* aspect of any programming language is scope of variables.
In Prolog, the scope of a variable is the clause that contains it.

In the fact knot(1, fetch(Variable)) you have a variable whose scope is
that fact ONLY.  It could use as well have been written
	knot(1, fetch(Rumpelstiltskin)).
In the fact knot(2, write(Variable)) you have a completely unrelated
variable whose scope is that clause.  It could have been written
	knot(2, write(Goldilocks)).

There is no connection between variables in different clauses.
For a parallel, consider

	void knot_1(void) { int Variable; Variable = fetch(); }
	void knot_2(void) { int Variable; printf("%d", Variable); }

in C.  Just as you would expect the two variables in the C code to be
unrelated variables despite their names being spelled the same, so you
should expect variables in different clauses in C to be unrelated.

What you should do is

	knot(1, X, fetch(X)).
	knot(2, X, write(X)).

	dynrule :-
	    knot(1, X, Body1), % NOT Rule1, because it isn't a rule
	    knot(2, X, Body2), % NOT Rule2, because it isn't a rule
	    assert(( testme :- Body1, Body2 )),
	    listing(testme),
	    testme.

	fetch(4).

and then you'll get

	?- dynrule.
	testme :-
		fetch(A),
		write(A).
	4

	Can anyone help me?  Have I to process the two parts of the rule
	as strings?

Of course not.  You have to treat them as Prolog data structures.
You just have to *say* which parts of the data structures are to be
shared with other contexts.

I suggest as a matter of urgency that you get yourself a good Prolog
textbook such as Sterling & Shapiro "The Art of Prolog" and read it.