Modules

58 views
Skip to first unread message

denis.be...@gmail.com

unread,
Nov 10, 2021, 4:34:34 AM11/10/21
to CLIPSESG
I think there's something missing in the Basic Manual about rules in modules.
What seems clear is, when rules are loaded (with no further module specification), they are loaded in the current module. And that seems to work. But it would be nice to have this stated explicitly somewhere in section 10 of the manual.
I think section 10 should also:
- state explicitly that rules are not imported, even with the ?ALL choice (it's a consequence of what's listed as being imported, but writing it wouldn't hurt);
- for completeness, refer to section 12.20 (Defmodule Functions). 

Also, according to section 10.6, when (run) is launched, the rules in the current module are fired first (unless there are special cases of auto-focus rules), regardless of their saliences wrt rules in other modules,  before focus is eventually passed to another module. After all, that's the whole point of modules, having them do some "local" processing, right?

I have a problem with the following example. Is there a bug in the modules code or am I missing anything?

;;; Module MAIN

(defrule foo ?f <- (foo ?x) => (retract ?f))

(deffacts init (foo 1))

(defmodule MAIN (export ?ALL))

;;; Module BAR

(defmodule BAR (import MAIN ?ALL))

;;; remember that rules are not imported

(defrule bar (foo ?x) => (assert (bar ?x)))


(reset)

(facts)

;;; f-0     (initial-fact)

;;; f-1     (foo 1)

;;; OK

(get-current-module)

;;; MAIN

(watch facts)

(watch rules)


(set-current-module BAR)

(get-current-module)

;;; BAR : OK

;;; until now, everything seems to work as expected

;;; BUT

(run)

;;; gives:

;;; FIRE    1 foo: f-1

;;; <== f-1     (foo 1)

(get-current-module)

;;; BAR


So, it seems that the rule in BAR was not fired, the rule in MAIN was fired, but the current module is still BAR.

From section 10.6 of the manual ("When a run command is given, the agenda of the module that is the current focus is executed"), I expected:

FIRE    1 bar: f-1

==> f-2     (bar 1)

FIRE    2 foo: f-1

<==  f-1     (foo 1)

(get-current-module)

MAIN



Notice that I tried this in version 6.3 and 6.4 (last release, 813) and I got the same results.


denis.be...@gmail.com

unread,
Nov 10, 2021, 9:54:05 AM11/10/21
to CLIPSESG
I found the problem: focus.
So, in order to use modules, one needs not only read the section (10) of the manual named "modules" (which refers to no other section). One needs also read not one  (12.20) but two (12.20 + 13.7) more sections.
I think both of them should be mentioned in section 10.

Anyway, I think the way section 10.6 is written is contradictory with the real workings.
"Each module has its own pattern-matching network for its rules and its own agenda. When a run command is given, the agenda of the module that is the current focus is executed (note that the reset and clear commands make the MAIN module the current focus). Rule execution continues until another module becomes the current focus, no rules are left on the agenda, or the return function is used from the RHS of a rule."

In my example, the current module is set to BAR before (run). So that the BAR agenda should be executed according to what's written above.

denis.be...@gmail.com

unread,
Nov 11, 2021, 1:32:56 AM11/11/21
to CLIPSESG
I found another place in section 10.6 of the manual that could be improved:.
Section 3.4:
"Asserting or referring to an ordered fact (such as in a LHS pattern) creates an “implied” deftemplate with a single implied multifield slot named implied."
Section 10.6:
"Only deftemplates, defclasses, defglobals, deffunctions, and defgenerics may be exported."
From this, I conclude that ordered fact are also inherited when ?ALL is selected in import and export clauses.
I think this should be stated explicitly in section 10.6.

CLIPS Support

unread,
Nov 27, 2021, 9:58:41 PM11/27/21
to CLIPSESG
I've added the changes you've suggested.
Reply all
Reply to author
Forward
0 new messages