From ok@atlas.otago.ac.nz Thu Mar 29 02:53:03 2001
Received: from atlas.otago.ac.nz (atlas.otago.ac.nz [139.80.32.250])
	by swi.psy.uva.nl (8.11.2/8.11.2) with ESMTP id f2T0r1325809
	for <prolog@swi.psy.uva.nl>; Thu, 29 Mar 2001 02:53:02 +0200 (MET DST)
Received: (from ok@localhost)
	by atlas.otago.ac.nz (8.9.3/8.9.3) id MAA23282;
	Thu, 29 Mar 2001 12:52:49 +1200 (NZST)
Date: Thu, 29 Mar 2001 12:52:49 +1200 (NZST)
From: "Richard A. O'Keefe" <ok@atlas.otago.ac.nz>
Message-Id: <200103290052.MAA23282@atlas.otago.ac.nz>
To: konik@umich.edu, prolog@swi.psy.uva.nl
Subject: Re:  [SWIPL] global dynamic predicates shared in different modules?

"Tolga Konik" <konik@umich.edu> wrote:
	I write a program which has modules m1, m2,..
	I want them to share some dynamic predicates p1,p2,.. globally.
	For example
	assert(p1(1)) called in m1 and m2 should have the same effect. (not
	assert(m1:p1(1)) and assert(m2:p1(1)))
	
	what is the cleanest way of doing this?

The cleanest way is *DON'T*.

Each dynamic predicate should be "owned" by exactly one module,
and all changes to that dynamic predicate should go through
interface predicates exported from the module.

    :- module(p1_owner, [p1/1, assert_p1/1, retractall_p1/1]).
    :- dynamic raw_p1/1.

    p1(X) :- raw_p1(X).

    assert_p1(X) :-
	( integer(X) -> assert(raw_p1(X) ; report error somehow ).

    retractall_p1(X) :- retractall(raw_p1(X)).

where you'll note that I've suggested adding code to the maintenance
predicates that ensures the facts in the table always make sense.

Modules are all about encapsulation and abstraction; letting other
modules change your data without giving you a chance to check and
interface violates encapsulation and abstraction in the worst possible way.

Ok, so what's the next best way?

Use another language, maybe Java, where people don't really believe in
encapsulation and all that other OO stuff.  (:-)

