Home->
Software->UPS
UPS: The Unoffical Production System
Reference: OPS5 Language Introduction, Michael Mauldin, October, 1992
For applications requiring the rule based decision making on thousands
of parallel or simultaneous input patterns, the "Unofficial" Production
System, UPS, can be applied to identifying these patterns. UPS is a
parallel system based on the classical Rete model in OPS-5.
A production system, PS, is made up of if-then relatonships or
a MATCH-RESOLVE-ACTION, MRA process.
if (condition) --> then (action or function)
The statements containing the if-then clauses can be decomposed
into the left-hand side, LHS, containing the conditions, and the
right-hand-size, RHS, containing the actions.
The conditional elements, CEs, on the LHS, are symbolic representations
of classes and their attributes. The actions on the, RHS, are
executable function elements, FEs.
The PS algorithm handles the dependency between the conditional
elements, CE, and the functional elements, FE. The PS algorithm
runs inside the black box between the CEs and FEs.
CE --> box_WMEs --> FE
The results of the FEs are feedback into the black box.
In lisp style language:
(p production_name
(class-name (attribute_name value) [(^attr value) ...])
-->
(action class-name (attribute_name value) [(^attr value) ...])
The lisp style predicates on the LHS define objects, and the
predicates on the RHS are more like functions containing the
objects as arguments; a form of lambda functions.
Sample programs:
   major.ops
   demo.ops
   monkeys-and-bananas.ops
   conflict.ops
   tic-tac-toe.ops
DATA TYPES
Atoms
Numeric
Integers
EBNF:
decimalDigit ::= 0|1|2|3|4|5|6|7|8|9
integer ::= [+|-] decimalDigit {decimalDigit} [.]
For example,
+42
12
6.
-56.
Floating-point
EBNF:
exp ::= e integer
float ::=
[+|-] {decimalDigit} [.]
decimalDigit {decimalDigit} [exp]
For example,
0.0
2.717
-.3e+22
42e+2
Symbolic
Any atom (sequence of characters) which has no numeric meaning is a
symbolic atom.
Predefined
NIL
User-defined, for example,
LEE
Lee
grant
927-2300
255 Grapevine Road
South_Boston
South Boston
(apple)
(apple {orange) kumquat)
a^;(
?-c
Note: To include spacing, parentheses, braces, circumflex or semicolons
the atoms must be delimited by vertical bars, that is,
|255 Grapevine Road|
|South Boston|
|(apple)|
|(apple {orange) kumquat)|
|a^;(|
Atoms delimited by vertical bars are called "quoted atoms." The VAX OPS5
runtime system does not distinguish between case in characters used
in atoms, unless they are quoted. Thus, Lee and LEE are synonyms,
but |Lee| and |LEE| are unique.
WORKING MEMORY
Working memory elements are declared in the first section of an OPS5
program. An element class is decalred with the literalize
command, whose EBNF is,
(literalize className {attributeName})
For example, we might declare a class called student as follows,
(literalize Student
id
gpa
current-class
major
major-2
major-3
minor-1
minor-2
)
which indicates that the production system will contain data about Student
entities, for whom seven different attributes have been declared. Note that
Student is the className, and gpa through minor-2 are attributes of the
class. Note, also, that the language does not require (or allow) us to
declare the types of the attributes, only their names. Thus, gpa could
contain the values 3, 2.45, pi or even Howdy-Doody.
As indicated in the EBNF, a class need not have attributes, for example,
it is common to define context classes such as,
(literalize Print-Results)
to control flow of the OPS5 program, as described later. It is important
to distinguish the difference between the declaration of an element class
from the actual instantiation of working memory elements (WMEs).
Declaring a class does not reserve memory locations. In order to actually
create a WME, one uses the make command, for example,
(make Student ^id 99666666 ^gpa 2.10 ^major CS ^minor MA ^minor-2 CH)
(make Student ^id 99777777 ^gpa 3.0 ^major CS ^minor BI ^minor-2 YM)
(make Student ^id 99888888)
(make Student ^major-2 EN)
(make Student)
instantiates five WMEs with the attribute values inidicated. Any attribute
that is not explicitly instantiated with a value will be initialized with
the value NIL.
Working memory elements have two additional fields associated with them.
To examine working memory, the OPS5 command wm is used,
OPS>wm
1 [NIL] (STUDENT ^ID 99666666 ^GPA 2.10 ^MAJOR CS ^MINOR MA ^MINOR-2 CH)
2 [NIL] (STUDENT ^ID 99777777 ^GPA 3.0 ^MAJOR CS ^MINOR BI ^MINOR-2 YM)
3 [NIL] (STUDENT ^ID 99888888)
4 [NIL] (STUDENT ^MAJOR-2 EN)
5 [NIL] (STUDENT)
In this view of the working memory, the first number is referred to as
the time tag for the memory element. The larger the number, the more
recent the memory element. A memory element's time tag is set when it
is first instantiated and is updated anytime the element is modified.
The bracketed symbolic-atom is the name of the production which
instantiated/modified the element. In this case, the elements were
instantiated without the use of a production, thus the predefined symbol
NIL is used in place of the normal production name.
STRUCTURED DATA
Each class element can have at most one multi-valued attribute called a
vector attribute. Vector attributes are declared as follows,
(vector-attribute vectorName {vectorName})
for example,
(vector-attribute airlines-flown)
which declares airlines-flown to be a vector when used as an attribute
name in a literalize command. Note that the order on the vector-attribute
and literalize commands is irrelevant in the language, yet it is
recommended that vector attributes are declared before use in a literalize,
to improve readability. Several vector attributes can be declared at once,
as in,
(vector-attribute
airlines-flown ; for example, DL US AA BA
hotels-stayed ; for example, HILTON, MARRIOTT, MOTEL6
rental-car-companies-used ; for example, HERTZ, AVIS, BUDGET
)
(literalize Employee
name ; for example, |LEVY I|
idNumber ; for example, 12345
total-frequent-flier-miles ; for example, 230145
airlines-flown ; the vector attribute
)
etc. The example above indicates that white space may be used at the
programmer's discretion. Also, note the use of semicolons to mark
comments to the end of the current line.
PRODUCTIONS
The OPS5 program is a collection of rules known as productions. Productions
have the form,
LHS Conditions --> RHS Actions
where the condition elements are collectively referred to as the left-hand
side of the production and the actions are referred to as the right-hand
side of the production.
The OPS5 syntax for productions is,
(p production-name
LHS
-->
RHS
)
Productions may have any symbolic name except NIL.
LHS CONDITIONS
The condition elements in an OPS5 production are used by the
Match-Resolve-Action, MRA, cycle to chose which actions to perform. In
this way, the condition elements serve as the only explicit form of
control structure in the language.
Condition elements are parenthesized and always begin with the name of a
working memory element data class. For example, the condition element,
(student)
would simply be an assertion that one or more student class elements were
currently found in working memory. Every LHS must have from 1 to 32
condition elements of this form (referred to as positive condition
elements). It is possible to be more specific in the specification of
these elements, though. For instance,
(student ^id 99777777)
would only be satisfied if there was one (or more) WME with class student
and id attribute equal to 99777777. Equality is not the only possible
test when matching condition elements to the working memory. Predicates
supported by OPS5 are,
Any types of data
= Same type as and equal to (default)
<> Not same type as or not equal to
== Same type as
Integer or Floating-point only
< Same type as and less than
<= Same type as and less than or equal to
> Same type as and greater than
>= Same type as and greater than or equal to
Thus, we could use the following,
(student ^gpa > 3.0)
to select from among the WME's for student class satisfying the condition
of gpa attribute greater than 3.0. More complex criteria are possible by
the inclusion of conjunctions (AND conditions) or disjunctions (OR
conditions) whose syntax follows.
Conjunctions
Conjunctions are written as a curly-brace delimited set of conditions.
For instance,
{ > 3.0 > 3.5 }
would be a test to ascertain that a value was greater than 3.0 AND less
than 3.5. The conjunction can be used in a condtion element such as,
(student ^gpa { > 3.0 < 3.5 })
Disjunctions
Disjunctions are wwritten as a double-angle-bracket delimited set of
conditions. For example,
<< moe curly larry >>
would be used to test for equality (the default predicate) to the symbol
moe OR curly OR larry. Recall that case is not significant unless the
symbol is quoted.
Negative Condition Elements
A negative condition element is a condition element which is preceded
with a negative sign. An LHS may have any number of negative condition
elements. A negative element asserts that a given WME does not exist.
For example,
- (student)
would assert that no student class WME's are instantiated. Further,
- (student ^gpa { > 3.0 < 3.5 })
would assert that working memory does not contain any WME's for student
classes with gpa attribute greater than 3.0 and less than 3.5. Next
consider the following two conditions elements,
(student ^gpa <> 4.0)
versus,
- (student ^gpa 4.0)
At first glance, these seem to have the same meaning, but that is not
correct. In the first case, the condition element will only be satisfied
if a) there exists at least one student class WME which b) has gpa
attribute not equal to 4.0.
The second condition means, there is not a student class WME which has a
gpa equal to 4.0. Note that the subtle difference is that this is true
even if there are NO student class WME's.
Variables
Variables in OPS5 are denoted by atoms enclosed in angle brackets such as,
< gpa >
The scope of all variables is the production in which it is used. There is
no global communication between variables. The first use of a variable in a
production bind a value to the symbolic name. Each subsequent use of the
variable references the bound value (there is an exception since OPS5 has
an action which allows a bound value to be changed).
Variables are particularly useful when writing a sequence of condition
elements, such as,
(student ^id <id-1> ^major <major>)
(student ^id { <id-2> <> <id-1> } ^major <major>)
This sequence of conditions can be read as follows,
a. A student class WME exists with a given is and major attribute value,
b. A second student class WME exists with a different id value and the
same major value, and
c. <id-1>, <id-2> and <major> are bound to the values
of the given WME attribute values for the remainder of the production.
Variables are also useful for communicating a value bound from working
memory to the RHS of a production for a subsequent action.
RHS ACTIONS
The right hand side of a production contains the actual actions to be
performed by the program. These action include creating, modifying
and deleting WME's, halting the program explciitly, compute arithmetic
values, and performing I/O operations. Other advanced features are also
available but are outside the scope of this handout.
Working memory actions
Three actions are available to modify the working memory. They are make,
remove and modify.
make
To create a WME during runtime, the make action is used. The syntax for
a make action is,
(make className {attributeName value})
For example,
(make student)
(make student ^gpa 4.0)
(make student ^id <id-2> ^major CS)
would create three new WME's of class student. The first would have no
explicit values bound to its attributes (thus they would all implicitly
be bound to NIL). The next WME would have all attributes NIL except for
gpa which would be set to 4.0. The third WME would have the id attribute
set to the value which had previously been bound to <id-2> in the same
production. Further, the major attribute of this WME would be set to CS.
remove
To delete a WME, the remove action is used. The syntax for a remove is,
(remove conditionNumber)
This form used used to associate a WME with a condition which it matches.
For example, consider the complete production,
(p example-1
(student ^gpa > 4.0) ; error data
-->
(remove 1)
)
which means, if a WME of class student exists with a gpa attribute
greater than 4.0, then remove that WME from the working memory. Note
that the number 1 in the remove action indicates that the first (and
only) condition is the one that designates the WME to be removed. A
more complex example is,
(p example-2
(student ^gpa { > 3.5 <= 4.0 })
(student ^gpa > 4.0) ; error data
-->
(remove 2)
)
Note that the number is remove now indicates that the SECOND condition
element is the element which matches the WME to be deleted.
modify
To change the values in a WME without removing the WME and making a new
one, the modify action is used. The syntax for modify is,
(modify conditionNumber {attributeName value})
For example,
(p example-3
(student ^gpa { > 3.5 <= 4.0 })
(student ^gpa > 4.0) ; error data
-->
(modify 1)
(modify 2 ^gpa 4.0)
)
would update the time tag of the WME matching the first condition element
and would both update the time tag and the gpa attibute value of the WME
matching the second condition element. Values may be literal, computed
or bound to a variable. For example,
(p example-4
(student ^gpa { <gpa> > 3.5 <= 4.0 })
(student ^gpa > 4.0) ; error data
-->
(modify 2 ^gpa )
)
would update the value of the WME matching the second condition element
by changing its gpa attibute to the value which was bound to <from the
WME matching the first condition. As always, the time tag of the WME is
updated when the element is modified. Note that in this case, though,
the WME matching the first condition is not affected at all, thus its
time tag is unchanged.
Computational actions
compute
Compute is not actually an action, per se, but is a function which returns
a value. Usually this (and other) functions are used on the RHS of an
OPS5 production; however, they may also be used on the LHS for some purposes.
Compute allows arithmetic computations using the following operators,
+ Addition
- Subtraction
* Multiplication
// Division
\\ Modulus (integer data only)
OPS5 uses infix notation and performs all operations at the same level of
precedence, evaluated right to left. Thus,
(compute 2 + 3 * 4 + 5)
evaluates to 29, not 19. To override these rules, parenthesized expressions
may be used, for example
(compute 2 + (3 * 4) + 5)
which evaluates to 19.
Important notes!
1. As shown above, all values must be separated from
operators by whitespace.
2. OPS5 determines the type of an arithmetic expression
from the values bound.
For example,
22 // 5
returns 4 (the integer result of 2 divided by 5. But consider the following
floating-point expressions and their results:
2 // .5 returns 4.0
.2 // 5 returns 0.4000000E-01
.2 // .5 returns 0.4
Mixed-mode expressions evaluate as floating-point, such as,
22.0 // 5 returns 4.4
I/O actions
File actions
mode ::= IN | OUT | APPEND
(OPENFILE logical-file VAXfilename mode)
(CLOSEFILE logical-file) action
Input functions
(ACCEPT [logical-file]) function
(ACCEPTLINE [logical-file] [default-value]) function
Output actions/functions
(WRITE) action
(CRLF) function
(TABTO n) function
(RJUST n) function
For example,
(WRITE |The value stored is: | (CRLF))
PROGRAM FLOW IN OPS5
Programs are not written like programs in other paradigms. For example,
there is no traditional control structure in the language. The notion of
sequential, conditional and repetitive control is replaced by a
Match-Resolve-Action algorithm which can be described as,
repeat
perform a match between working memory and production memory
exit if any of the following are true
the conflict set is empty
a halt was performed
the cycle count has been reached
a breakpoint has been reached
perform conflict resolution via given strategy
fire the selected rule
end
Thus, it is not obvious what order the productions which comprise the
program will be executed without also knowing what data will be provided.
One cycle of the MSE algorithm can be described in detail by considering an
actual example. When a rule is satisfied by one or more matches in WM, then
those matches become elements of the conflict set. When selecting an
element of the conflict set, the following criteria are used to choose among
the elements,
REFRACTION
This term comes from the neurobiological observation of a
refractory period for a neuron, which means that the neuron
is not able to fire immediately without first going through a
relaxation process. In a similar way, OPS5 will not allow the
same instantiation in the conflict set from firing twice in a row.
This prevents the inference engine from entering into an infinite
loop.
RECENCY
When selecting between two instantiations, select the one whose time
tag is most recent, at the first point of difference.
SPECIFICITY
If the recency of two or more instantiations is equal, select the
most specific instantiation. Specificity is determined by the
number of conditions which must be met by the LHS of the production.
Each of the following is considered to be a test by the LHS:
Class name
Disjunction
Value preceeded by a predicate (except in a disjunction)
All occurrences of a variable, except the first
To understand this conflict resolution strategy, consider the following
state of working memory,
#1 1 [NIL] (VALUE ^DATA 1)
#2 2 [NIL] (VALUE ^DATA 42)
#3 3 [NIL] (VALUE ^DATA -4)
#4 4 [NIL] (VALUE ^DATA 1 ^TYPE NUMBER ^POSITIVE TRUE)
#5 5 [NIL] (VALUE ^DATA 77 ^POSITIVE TRUE)
#6 6 [NIL] (BEGIN)
and the following productions,
(p rule-1
(begin)
(value ^data < 0 ^positive NIL)
-->
(modify 2 ^positive FALSE)
)
(p rule-2
(begin)
(value ^data > 0 ^positive NIL)
-->
(modify 2 ^positive TRUE)
)
(p rule-3
(begin)
(value ^data { > 0 })
- (value ^data > )
- (value ^positive NIL)
-->
(write |Largest value: | (tabto 20) (crlf))
(remove 1)
(remove 2)
(make normal-values)
)
(p rule-4
(normal-values)
(value ^data )
- (value ^data > )
-->
(write (tabto 20) (crlf))
(remove 2)
)
(p rule-4-specific
(normal-values)
(value ^data ^positive TRUE)
- (value ^data > )
-->
(write (tabto 20) (crlf))
(remove 2)
)
The program, a file with extention .ops, is entered via the text editor.
To compile the source code give the command:
$ ups filename
To enter the OPS environment enter:
$ filename
We can examine the intial conflict set by using the command,
OPS5>cs
RULE-1 #6 6 #3 3
RULE-2 #6 6 #2 2
RULE-2 #6 6 #1 1
Note that this means that three instantiations are vying for selection at
this time. RULE-1 matches its first condition to WME #6 (time tag 6) and
WME #3 (time tag 3). RULE-1 also matches WME #6 and WME #2 (time tag 2).
The conflict resolution strategy says that Recency is the first
consideration. Hence, 6|3 is more recent than 6|2 or 6|1. Thus, RULE-1
fires using the data from WME's with time tags 6 and 3, leaving WM:
OPS5>run 1
OPS5>wm
#1 1 [NIL] (VALUE ^DATA 1)
#2 2 [NIL] (VALUE ^DATA 42)
#4 4 [NIL] (VALUE ^DATA 1 ^TYPE NUMBER ^POSITIVE TRUE)
#5 5 [NIL] (VALUE ^DATA 77 ^POSITIVE TRUE)
#6 6 [NIL] (BEGIN)
#3 7 [RULE-1] (VALUE ^DATA -4 ^POSITIVE FALSE)
and the second conflict set is,
OPS5>cs
RULE-2 #6 6 #2 2
RULE-2 #6 6 #1 1
again, Recency is the deciding factor. RULE-2 will fire with time tags 6
and 2 as the WME's. On the third cycle, RULE-2 will fire with time tags 6
and 1, leaving,
OPS5>run 2
OPS5>wm
#4 4 [NIL] (VALUE ^DATA 1 ^TYPE NUMBER ^POSITIVE TRUE)
#5 5 [NIL] (VALUE ^DATA 77 ^POSITIVE TRUE)
#6 6 [NIL] (BEGIN)
#3 7 [RULE-1] (VALUE ^DATA -4 ^POSITIVE FALSE)
#2 8 [RULE-2] (VALUE ^DATA 42 ^POSITIVE TRUE)
#1 9 [RULE-2] (VALUE ^DATA 1 ^POSITIVE TRUE)
OPS5>cs
RULE-3 #6 6 #5 5
RULE-3 contains the write action, so output is generated in this cycle
and the conflict set becomes,
RULE-4 #7 10 #2 8
RULE-4-SPECIFIC #7 10 #2 8
Note that in this case, Recency is not useful since both rules refer to
the same time tags. In that case, we next look to Specificity as the
dominant ruler. In RULE-4 the LHS contains 4 tests, while
RULE-4-SPECIFIC contains 5 tests, thus the more specific rule fires.
(p rule-4
(normal-values) ; 1 test
(value ^data <x>) ; 1 test
- (value ^data > <x>) ; 2 tests
-->
(write (tabto 20) <x> (crlf))
(remove 2)
)
(p rule-4-specific
(normal-values) ; 1 test
(value ^data <x> ^positive TRUE) ; 2 tests
- (value ^data > <x>) ; 2 tests
-->
(write (tabto 20) <x> (crlf))
(remove 2)
)
OPS5 TOP LEVEL COMMANDS
Running a compiled OPS5 executable file:
$ filename
OPS5 Environment Commands
Note: All of the following commands can be issued at the OPS5> prompt
or within the STARTUP statement of the program. Other commands are also
available; consult the OPS5 Reference Manual for further details.
filename [n] go forward n cycles, or until
halted if no n is given
watch 0|1|2|3|4 watch 0 - no trace information
watch 1 - display productions executed / time tags
watch 2 - above plus show modifications to WM
watch 3 - above plus show modifications to CS
watch 4 - above plus show modifications to PM
back [n] backs up from previous cycles
enable back record status information to allow backing up
cs show current conflict set
wm {n} show content of working memory element(s) n,
or the entire WM if not n is given
restart reset WM to beginning
matches rule for each condition element of the rule,
shows WME's which match
show space | back memory usage, cycles stored
report timing writes two text files, TIMINGCPU.TXT and
TIMINGCAU.TXT which
report statistics related to the
run of the program.
enable timing begin recording data for timing report
OPS5 Language
Production
A production-rule is a list containing
* a function call to p
* LHS: one or more condition elements (first not negated),
each in Lisp format.
* a separator -->
* RHS: one or more actions, each in Lisp format.
Sample Rule
-----------
;; IF the key is on AND the engine is not turning
;; THEN conclude that the problem is in the starting system
(p bad-starting-system
(task ^goal diagnose)
(fact ^name |key is off| ^value no)
(fact ^name |engine is turning| ^value no)
-->
(bind |problem is in starting system|)
(make fact ^name ^value yes)
(write (crlf) Concluding (crlf))
)
Left-Hand Side
--------------
LHS is collection of patterns to be matched against
working memory. Each pattern contains a class name
followed by some number of LHS terms.
Each term consists of an ^attribute-name followed
by a LHS-value.
The LHS-value can be a
(1) constant
In pattern ^on couch, couch is a constant.
In pattern ^GRE 100, 100 is a constant.
(2) variable
In pattern, ^Status , is variable that will be
bound during matching to an actual value for some element
in working memory.
predicate operator
One of seven operators may precede a constant or variable:
=, <>, <=>, <, <=, >=, >.
The = is assumed if no operator is present.
disjunction
In the pattern ^weight << light medium >>,
<< light medium >> specifies
that only one of the set of values, light and medium,
must match. Any LHS-values may be contained in
the disjunction.
Warning: leave spaces between values and angle brackets
to avoid confusing them with variable brackets.
conjunction
In pattern ^GRE { > 600 < 800 }, { > 600 < 800 }
specifies a set of value restrictions all of which
must match.
Any LHS-values may be contained in the conjunction.
Restrictions to predicate operators:
1. <, <=, >= and > are used only with numbers and with
variables bound to numbers. <=> means same type,
and <> means not equal.
2. The first occurrence of a variable cannot be
preceded by any predicate other than = (first occurrence
establishes binding). A condition pattern in LHS
(other than first) may be negated by putting a "-" in
front of the normal pattern.
The ordering of condition elements is significant in
variable binding, for conflict resolution and for
match efficiency.
4 RHS of OPS5 Rules
* The RHS of the OPS5 rule consists of an ordered
sequence of actions.
* The primitive actions that affect working memory
are make, modify, and remove.
* The write action is used to output information.
* The halt action provides a way of explicitly
stopping the firing of production rules.
* RHS can also contain functions that return values
within the actions.
For example, the compute function allows OPS5 to do arithmetic.
It provides for infix evaluation of +,-,*, //, and \\
(respectively addition, subtraction, multiplication, division,
and modulus). Operations are performed from right to left.
Specific Commands
-----------------
The WATCH Command
* no argument Print current watch level (initialized to 1)
unchanged
(watch 0) - No report of firings or changes to working memory
(watch 1) - Report rule name and time tags of each working
memory element for each instantiation fired
(watch 2) - In addition to level 1 reports, give each change
(add or delete) to working memory
The RUN Command
(run) - run until a break or halt or no rules in conflict set
(run N) - run N steps unless early stop as above
(run 1) - for single stepping
The WM and PPWM Commands
(wm) - list the contents of working memory, optional
arguments specify time tags; if no time tags are
given, shows all elements.
(ppwm ) - is pattern (in LHS condition form),
prints all wmes that match .
No variables, predicates or special
characters are allowed in in .
If pattern is null, all elements are printed.
* Use with cs and matches to determine why a rule failed to be
instantiated at the right time.
The PM Command
(pm ) - any number of rule names
The CS Command
(cs) - lists each instantiated rule in conflict set, one
to a line, followed by currently dominant instantiation
(that is, the one to be fired on next cycle)
The MATCHES Command
(matches ) -- prints partial matches for rules
whose names are arguments. For each condition element
of specified rules, time tags of matching wme.s are listed,
as well as intersections of partial matches.
(literalize number value)
(p example-rule
(number ^value { > 100 } )
(number ^value { <> } )
(number ^value { < 50 } )
-->
(write (crlf) )
)
(make number ^value 101) ; given time-tag 1
(make number ^value 102) ; given time-tag 2
(make number ^value 11) ; given time-tag 3
=>(matches example-rule)
example-rule
** matches for (1) **
2
1
** matches for (2) **
3
2
1
** matches for (2 1) **
3 1
3 2
1 2
2 1
** matches for (3)
3
nil
The final intersection, which in this example would
be matches for (3 2 1), is not included.
Uses:
* a given condition element is never matched,
* the intersection of two or more condition elements,
each of which is matched, fails to be satisfied,
or a negated condition element is matched.
The PBREAK Command
(pbreak ) - toggles break/nobreak status of rules
(pbreak) - says which rules are broken
* breaks after rule fires
The BACK Command
(back ) - undoes the effects of up to 32 rule
firings, provided there are no external
references (user-defined functions) in any RHS
The MAKE and REMOVE Commands
(remove *) - deletes everything from working memory.
(remove ) - deletes working memory elements with
time tags in
The EXCISE Command
(excise ) - prevents rules from firing
(still in network), reload to recall,
but won't be current on wm.