next up previous

5.4.1.4 Connective Constraints

Three connective constraints are available for connecting individual constraints and variables to each other. These are the & (and), | (or), and ~ (not) connective constraints. The & constraint is satisfied if the two adjoining constraints are satisfied. The | constraint is satisfied if either of the two adjoining constraints is satisfied. The ~ constraint is satisfied if the following constraint is not satisfied. The connective constraints can be combined in almost any manner or number to constrain the value of specific fields while patternmatching. The ~ constraint has highest precedence, followed by the & constraint, followed by the | constraint. Otherwise, evaluation of multiple constraints can be considered to occur from left to right.

Basic Syntax

Connective constraints have the following basic syntax:

<term-1>&<term-2> ... &<term-3>
<term-1>|<term-2> ... |<term-3>
~<term>

where <term> could be a singlefield variable, multifield variable, constant, or connected constraint.

Syntax

Expanding on the syntax definition given in section 5.4.1.3 now gives:

<constraint> ::= ? | $? | <connected-constraint>
<connected-constraint>
             ::= <single-constraint> |
                 <single-constraint> & <connected-constraint> |
                 <single-constraint> | <connected-constraint>
<single-constraint> ::= <term> | ~<term>
<term> ::= <constant> |
           <single-field-variable> |
           <multifield-variable>

The & constraint typically is used only in conjunction with other constraints or variable bindings. Notice that connective constraints may be used together and/or with variable bindings. If the first term of a connective constraint is the first occurrence of a variable name, then the field will be constrained only by the remaining field constraints. The variable will be bound to the value of the field. If the variable has been bound previously, it is considered an additional constraint along with the remaining field constraints; i.e., the field must have the same value already bound to the variable and must satisfy the field constraints.

Example 1

CLIPS> (clear)
CLIPS> (deftemplate data-B (slot value))
CLIPS>
(deffacts AB
  (data-A green)
  (data-A blue)
  (data-B (value red))
  (data-B (value blue)))
CLIPS>
(defrule example1-1
  (data-A ~blue)
  =>)
CLIPS>
(defrule example1-2
  (data-B (value ~red&~green))
  =>)
CLIPS>
(defrule example1-3
  (data-B (value green|red))
  =>)
CLIPS> (reset)
CLIPS> (facts)
f-0     (initial-fact)
f-1     (data-A green)
f-2     (data-A blue)
f-3     (data-B (value red))
f-4     (data-B (value blue))
For a total of 5 facts.
CLIPS> (agenda)
0      example1-2: f-4
0      example1-3: f-3
0      example1-1: f-1
For a total of 3 activations.
CLIPS>

Example 2

CLIPS> (clear)
CLIPS> (deftemplate data-B (slot value))
CLIPS>
(deffacts B
  (data-B (value red))
  (data-B (value blue)))
CLIPS>
(defrule example2-1
  (data-B (value ?x&~red&~green))
  =>
  (printout t "?x in example2-1 = " ?x crlf))
CLIPS>
(defrule example2-2
  (data-B (value ?x&green|red))
  =>
  (printout t "?x in example2-2 = " ?x crlf))
CLIPS> (reset)
CLIPS> (run)
?x in example2-1 = blue
?x in example2-2 = red
CLIPS>

Example 3

CLIPS> (clear)
CLIPS> (deftemplate data-B (slot value))
CLIPS>
(deffacts AB
  (data-A green)
  (data-A blue)
  (data-B (value red))
  (data-B (value blue)))
CLIPS>
(defrule example3-1
  (data-A ?x&~green)
  (data-B (value ?y&~?x))
  =>)
CLIPS>
(defrule example3-2
  (data-A ?x)
  (data-B (value ?x&green|blue))
  =>)
CLIPS>
(defrule example3-3
  (data-A ?x)
  (data-B (value ?y&blue|?x))
  =>)
CLIPS> (reset)
CLIPS> (facts)
f-0     (initial-fact)
f-1     (data-A green)
f-2     (data-A blue)
f-3     (data-B (value red))
f-4     (data-B (value blue))
For a total of 5 facts.
CLIPS> (agenda)
0      example3-3: f-1,f-4
0      example3-3: f-2,f-4
0      example3-2: f-2,f-4
0      example3-1: f-2,f-3
For a total of 4 activations.
CLIPS>


next up previous