/*  CLIPS Version 4.20C-Beta 2/12/88 */
0MBEGIN-ENTRY-MAIN

HELP_USAGE       RHS_SYNTAX
LIST_OF_TOPICS   USING_CLIPS
CLIPS_OVERVIEW   APPENDICES
LHS_SYNTAX       TEXT_PROCESSING

END-ENTRY

1IBEGIN-ENTRY-HELP_USAGE

HELP_USAGE

H.2 Using the Help Facility
The first call to the help facility will take longer than successive calls,
for the system is loading the help information into an internal lookup
table.  All later lookups will be virtually instantaneous (unless the help file
is unloaded - see Text Processing - Toss).

The help facility displays menus of topics and prompts the user for a choice.
It then references the file named in CLIPS.H for that information.  The help
facility can be called with or without a command-line topic.

Syntax :
  
  (help [<path>])

where <path> is the full path leading to a topic in the help tree.
For example, to access the entry on run-time error messages, you would
type : (help appendices error_messages run-time_errors).

Each element or field in the path is delimited by white-space, and the help
facility is not case sensitive.  In addition, the entire name of a field need
not be specified. Only enough characters to distinguish the field from other
choices in the menu are necessary (if there is a conflict, the help facility
will pick the first one in the list).  For instance, (help app err run) would
be sufficient for the above example.

There are a few special fields that can be specified :
  ^    -  Branch up one level.
  ?    -  When specified at the end of a path, this forces a display of
          the current menu, even on branch-ups.
<nil>  -  Giving no topic field will branch up one level.

A branch-up from the MAIN topic root node implies an exit from help.

By default, the help facility comes up in the MAIN topic root menu, and the
user may make a choice as described above.  The prompt line always displays
the name of the current menu.  The help facility will branch through the
help-tree until instructed to exit by a branch-up from the top level (see
above).

The level of the help-tree does not remain constant between calls to the help
facility.  The level is alawys reset to MAIN upon exit.

END-ENTRY

1IBEGIN-ENTRY-LIST_OF_TOPICS

HELP
CLIPS_OVERVIEW
  RULES
  FACTS
  BASIC_CYCLE_OF_EXECUTION
  REFERENCE_MANUAL_SYNTAX
  DEFINING_CONSTRUCTS
    DEFINING_RULES
    DEFINING_INITIAL_FACTS
  COMMENTING_CLIPS_RULES
  INTEGRATION_WITH_OTHER_LANGUAGES

LHS_SYNTAX
  LITERAL_PATTERNS
  WILDCARDS
  VARIABLES
  CONSTRAINING_FIELDS
    LOGICAL_OPERATORS
    PREDICATE_FUNCTIONS
    CONSTRAINING_FIELDS_THROUGH_PATTERN_EXPANSION
  USING_TEST_TO_CONSTRAIN_VARIABLES
  CONSTRAINING_PATTERNS
    INCLUSIVE_OR
    EXPLICIT_AND
    PATTERN_NEGATION
  PATTERN_BINDINGS
  DECLARING_RULE_PROPERTIES
    ASSIGNING_RULE_PRIORITY

RHS_SYNTAX
  BASIC_ACTIONS
    CREATING_NEW_FACTS
       CALLING_EXTERNAL_FUNCTIONS
    REMOVING_FACTS_FROM_THE_FACT-LIST
    ASSERTING_A_STRING
    BINDING_VARIABLES
    STOPPING_CLIPS
  MULTI-FIELD_FUNCTIONS
    NUMBER_OF_ELEMENTS
    SPECIFYING_AN_ELEMENT
    FINDING_AN_ELEMENT
  CLIPS_I/O_SYSTEM
    LOGICAL_NAMES
    COMMON_I/O_FUNCTIONS
      OPEN
      CLOSE
      READ
      READLINE
      PRINTOUT
      FPRINTOUT
      FORMAT
  MATH_FUNCTIONS
    STANDARD_MATH_FUNCTIONS
    EXTENDED_MATH_FUNCTIONS
  ADDITIONAL_FUNCTIONS
    SYSTEM
    GENSYM
    SETGEN
    CALL
    IF...THEN...ELSE
    WHILE
    STRING_CONCATENATION
    USING_CLIPS_INTERFACE_COMMANDS

USING_CLIPS
  ENVIRONMENT_COMMANDS
  SYSTEM_STATUS_COMMANDS
  DEBUGGING_COMMANDS
  MEMORY_MANAGEMENT_COMMANDS
  ADDITIONAL_COMMANDS

APPENDICES
  DEFINED_FUNCTIONS
  VERSION_DIFFERENCES
  GLOSSARY
  ERROR_MESSAGES
    RUN-TIME_ERRORS
    RULE_PARSING_ERRORS

TEXT_PROCESSING
  ENTRY_FILE_FORMAT
  FETCH
  PRINT-REGION
  TOSS

END-ENTRY

1MBEGIN-ENTRY-CLIPS_OVERVIEW

CLIPS_OVERVIEW

2.0 CLIPS Overview
This section gives a general overview of CLIPS and the basic concepts used 
throughout this manual.

Subtopics :

  RULES                     DEFINING_CONSTRUCTS
  FACTS                     COMMENTING_CLIPS_RULES
  BASIC_CYCLE_OF_EXECUTION  INTEGRATION_WITH_OTHER_LANGUAGES
  REFERENCE_MANUAL_SYNTAX

END-ENTRY

2IBEGIN-ENTRY-RULES

CLIPS_OVERVIEW
  RULES
  
2.1 Rules
The primary method of representing knowledge in CLIPS is a rule. A rule is a 
collection of conditions and the actions to be taken if the conditions are
met. The developer of an expert system defines the rules which describe howto
solve a problem. The entire set of rules in an expert system is called
knowledge base. CLIPS provides the mechanism (the inference engine) which
attempts to match the rules to the current state of the system and applies
the actions. The current state is represented by a list of facts.

END-ENTRY

2IBEGIN-ENTRY-FACTS

CLIPS_OVERVIEW
  FACTS

2.2 Facts
Facts are the basic form of data in a CLIPS system. Each fact represents a 
piece of information which has been placed in the current list of facts, 
called the fact-list. Rules execute (or fire) based on the existence or 
non-existence of facts. A fact is constructed of several fields separated 
by spaces. Any number of fields may be stored in a fact, and the number of 
facts in the fact-list is limited only by the amount of memory in the 
computer. Facts may be asserted into the fact-list prior to starting 
execution and may be added (asserted) or removed (retracted) as the action 
of a rule firing.  If a fact is asserted into the fact-list that exactly 
matches a fact that already exists, then the new assertion will be ignored.

Each field within a fact can be one of three things: a number, a word, or a
string. A number is any field which consists only of numbers (0-9), a 
decimal point (.), a sign (+ or -), and optionally, an (e) for exponential 
notation with it's corresponding sign. Some examples are:

   237   15.09   +12.9   -32.3e-7

All numbers are stored as single precision floating point values, regardless
of whether or not a decimal point was included. The number of significant 
digits will depend upon the machine implementation. Roundoff errors may also
occur, again depending on the machine implementation.

A word in CLIPS is any set of characters that starts with an alphabetic 
character and is followed by zero or more letters (A-z), numbers (0-9), 
underscores(_), or dashes (-). The word is ended by a space. Some examples 
are:

   foo   Hello   B76-HI   bad_value

Spaces or other special characters may not be included within a word. CLIPS
is case sensitive, i.e. uppercase letters will only match with uppercase
letters.

A string is a set of characters that starts with a double quotes (") and is
followed by one or more letters (A-z), numbers (0-9), underscores(_), dashes
(-), spaces, or special characters (any printable character). A string ends
with double quotes. Double quotes or other special characters may be 
embedded within a field by placing a backslash (\) in front of the 
character. Some examples are:

   "foo"   "a and b"   "1 number"   "a\"quote"

Note that a string surrounded by double quotes will only match another 
string. Strings will not match a word or vice versa. Strings are sometimes
referred to as quoted strings.

CLIPS facts are free form, which means there are no reserved words. All 
fields may be of any allowed type, and there is no restriction on the 
ordering of fields. 

The first fact in the fact-list is automatically asserted by the system
during a reset. This fact, (initial-fact), can be treated like any other 
fact and may be matched or retracted.

END-ENTRY

2IBEGIN-ENTRY-BASIC_CYCLE_OF_EXECUTION

CLIPS_OVERVIEW
  BASIC_CYCLE_OF_EXECUTION

2.3 Basic Cycle of Execution
Once a knowledge base (in the form of rules) is built, and the fact-list is
prepared, CLIPS is ready to execute rules. In a conventional language, the
starting point, the stop point and the sequence of operations are explicitly
defined by the programmer. With CLIPS, the program flow does not need to be
defined quite so explicitly. The knowledge (rules) and the data (facts) are
separated and the inference engine provided by CLIPS is used to apply the
knowledge to the data. The basic execution cycle is:

1)   the knowledge base is examined to see if any rule's conditions have 
     been met,

2)   all rules whose conditions are currently met are activated and placed 
on the agenda. The agenda is essentially a stack. Rules are pushed onto the
stack when they are activated. If the priority of the new rule is less than
the rule currently on top of the stack, the new rule is pushed down the 
stack until all rules of higher priority are above it. Rules of equal or 
lower priority will remain below the new rule.

3)   the top rule on the agenda is selected and it's right hand side actions
     executed.

As a result of right-hand side actions, new rules can be activated or 
deactivated. This cycle is repeated until all rules that can fire have done
so, or until the rule limit is reached. The number of rule firings allowed 
in a cycle may be set by the programmer, and rule priorities can be assigned 
(see LHS_SYNTAX DECLARING_RULE_PROPERTIES ASSIGNING_RULE_PRIORITY).

END-ENTRY

2IBEGIN-ENTRY-REFERENCE_MANUAL_SYNTAX

CLIPS_OVERVIEW
  REFERENCE_MANUAL_SYNTAX

2.4 Reference Manual Syntax
The terminology used throughout this manual to describe CLIPS syntax is 
fairly common to computer reference manuals. Plain words or symbols are to 
be typed exactly as they appear, particularly parentheses. Symbols enclosed
in single angle brackets, such as <name>, represent a single field to be
defined by the user. Symbols enclosed in double angle brackets, such as 
<<pattern>>, represent one or more fields which must be defined by the user.
Symbols enclosed within square brackets, such as [<<comment>>] are optional
parameters. White spaces (tabs, spaces, carriage returns) are used by CLIPS
only as delimiters between fields and are otherwise ignored (unless inside
double quotes). Examples in this manual show recommended indentation style. 

Small pieces of C code are also used in this manual. The syntax used for C 
code is slightly different and is more in keeping with the convention used 
in standard C manuals.

END-ENTRY

2MBEGIN-ENTRY-DEFINING_CONSTRUCTS

CLIPS_OVERVIEW
  DEFINING_CONSTRUCTS

2.5 Defining Constructs
There are two defining constructs in CLIPS, defrule, and deffacts. All 
constructs in CLIPS are surrounded by parentheses. The construct opens with
a left parenthesis, and closes with a right parenthesis. Each pattern or
block within a construct also opens and closes with parentheses.

Subtopics :

    DEFINING_RULES    DEFINING_INITIAL_FACTS

END-ENTRY

3IBEGIN-ENTRY-DEFINING_RULES

CLIPS_OVERVIEW
  DEFINING_CONSTRUCTS
    DEFINING_RULES

2.5.1 Defining Rules
Rules are defined using the defrule construct. Each rule in CLIPS must have
at least one condition and one action. There is no limit to the number of
conditions or actions a rule may have (other than the limitation of actual
available memory).

Syntax:

      (defrule <name> ["<comment>"]
      (<<first pattern>>)
      [   
                ; Left-Hand Side
                ;       (LHS)
       (<<nth pattern>>)]
      =>
       (<<first action>>)
      [   
                ; Right-Hand Side
                ;       (RHS)
       (<<mth action>>)])    

where <name> is the name of the rule and is a word. The comment is optional
and can be any string enclosed within double quotes.  The Left-Hand side
(LHS) is made up of a series of one or more patterns which represent the
condition elements for the rule. There is always an implicit and surrounding
all the patterns on the LHS. On the Right-hand side (RHS) we have a list of
one or more actions to be performed when the LHS of the rule is satisfied.
The arrow (=>) separates the LHS from the RHS. Actions are performed
sequentially if and only if all condition elements on the LHS are satisfied.

Example:

   (defrule example-rule   "This is an example of a simple rule"
      (refrigerator light on)
      (refrigerator door open)
      =>
      (assert (refrigerator food spoiled)))

END-ENTRY

3IBEGIN-ENTRY-DEFINING_INITIAL_FACTS

CLIPS_OVERVIEW
  DEFINING_CONSTRUCTS
    DEFINING_INITIAL_FACTS

2.5.2 Defining Initial Facts
With the deffacts construct, facts can be added to the initial fact-list.
Facts asserted through deffacts may be retracted or pattern matched like any 
other fact. The initial fact-list, including any defined deffacts, is
reconstructed after a reset.
Syntax:

   (deffacts <name> ["<comment>"]
      (<<fact 1>>)
      [   
          
          
      (<<fact n>>)]) 

where <name> is a word used to identify the set of facts. An optional
comment may also be included. There may be multiple deffacts constructs.
Any number of facts may be asserted into the initial fact-list in each
deffacts statement.

Example:

   (deffacts initial-facts
      "This is a set of facts needed prior to execution"
      (refrigerator light on)
      (refrigerator door open)

END-ENTRY

2IBEGIN-ENTRY-COMMENTING_CLIPS_RULES

CLIPS_OVERVIEW
  COMMENTING_CLIPS_RULES

2.6 Commenting CLIPS Rules
As with any programming language, it is highly beneficial to comment the
code. Both defrule and deffacts allow a comment directly following the
construct name. Comments can also be placed within CLIPS code by using a
semicolon (;). Everything from the semicolon until the next return character
will be ignored by the CLIPS reader. If the semicolon is the first character
in the line, the entire line will be treated as a comment. Examples of 
commented code will be provided throughout the reference manual.

END-ENTRY

2IBEGIN-ENTRY-INTEGRATION_WITH_OTHER_LANGUAGES

CLIPS_OVERVIEW
  INTEGRATION_WITH_OTHER_LANGUAGES

2.7 Integration with Other Languages
When using an expert system, two kinds of integration are important; 
embedding CLIPS in other systems, and calling external functions from the
right or left hand side of a CLIPS rules. CLIPS was designed to allow both
kinds of integration.  

Using CLIPS as an embedded application allows the easy integration of CLIPS
with existing systems. It is useful in cases where the expert system is a
small part of a larger task, or needs to share data with other functions.
In these situations, CLIPS can be called as a subroutine and information 
may be passed both to and from CLIPS. Embedded applications are discussed 
in the Advanced Programming Guide.

It may also be useful to call external functions while executing a CLIPS
rule. CLIPS allows external function calls on both the LHS and RHS of a 
rule. On the LHS they can be called as predicate functions to allow 
specialized testing of a rule's conditions. On the RHS of a rule, they can 
be called for a number of reasons, such as a function to alert the user when
an error condition is detected. User defined external functions may also be
called from the top level of the interactive interface. CLIPS variables or 
literal values may be passed to an external function, and functions may
return values to CLIPS. The easy addition of external functions allows CLIPS
to be extended or customized in almost any way. The Advanced Programming 
Guide describes how to integrate CLIPS with functions or systems written in
C as well as other languages.

END-ENTRY

1MBEGIN-ENTRY-LHS_SYNTAX

LHS_SYNTAX

3.0 LHS Syntax- Conditions
This section describes the syntax of pattern on the LHS of a rule. These 
patterns represent the conditions that must be satisfied before a rule can
fire.

Subtopics :

  LITERAL_PATTERNS       USING_TEST_TO_CONSTRAIN_VARIABLES
  WILDCARDS              CONSTRAINING_PATTERNS    
  VARIABLES              PATTERN_BINDINGS
  CONSTRAINING_FIELDS    DECLARING_RULE_PROPERTIES

END-ENTRY

2IBEGIN-ENTRY-LITERAL_PATTERNS

LHS_SYNTAX
  LITERAL_PATTERNS

3.1 Literal Patterns
The most basic pattern is one that precisely defines the exact fact that will
match.  This is called a literal pattern All fields in a literal pattern must
be matched by all fields in a pattern in the fact-list. There are no
variables in a literal pattern.

Examples:

   Pattern on LHS of rule   Fact in the fact-list        Matches?
   (group left town)        (group left town)               Y
   (group left town)        (group in town)                 N
   (group in Houston)       (group in Houston)              Y
   (group in Houston)       (group in HOUSTON)              N
   (group in my home state) (group in "my home state")      N
   (data "a red flag")      (data "a red flag")             Y
   (data 1)                 (data 1.0)                      Y
   (data 100.321)           (data 100.3)                    N

Note that space or control characters inside double quotes (i.e in a string)
could cause problems. Also, roundoff errors could make it difficult to match
numerical values to more than 3 or 4 decimal places.

END-ENTRY

2IBEGIN-ENTRY-WILDCARDS

LHS_SYNTAX
  WILDCARDS

3.2 Wildcards- Single and Multi-field
CLIPS has two kinds of wildcard symbols that may be used to represent fields
in a pattern. These are the question, "?" and dollar-question, "$?" 
wildcards.  CLIPS interprets these wildcard symbols as standing in place of
some part of a fact. The question wildcard matches any value (number, word
or string) stored in exactly one field in the fact. It is a wildcard : 
single-field wildcard symbol. The dollar-question wildcard matches any value
in zero or more fields in a fact. It is a wildcard : multi-field wildcard
symbol, standing in the place of multiple fields. Single and multi-field
wildcards may be combined in a single pattern in any combination.

Examples:

   Pattern on LHS of rule   Fact in the fact-list   Matches?
   (data red ?)             (data red)                 N
   (data red ?)             (data red green)           Y
   (data red ?)             (data red "green")         Y
   (data red ?)             (data red green green)     N
   (data red ?)             (data green red)           N

   (data red $?)            (data red)                 Y
   (data red $?)            (data red green)           Y
   (data red $?)            (data red "green")         Y
   (data red $?)            (data red green green)     Y
   (data red $?)            (data green red)           N

   (data ? ?)               (data red)                 N
   (data ? ?)               (data red green)           Y
   (data ? ?)               (data red "green")         Y
   (data ? ?)               (data red green green)     N
   (data ? ?)               (data green red)           Y

   (data ? $?)              (data red)                 Y
   (data ? $?)              (data red green)           Y
   (data ? $?)              (data red "green")         Y
   (data ? $?)              (data red green green)     Y
   (data ? $?)              (data green red)           Y

   (data $? ?)              (data red)                 Y
   (data $? ?)              (data red green)           Y
   (data $? ?)              (data red "green")         Y
   (data $? ?)              (data red green green)     Y
   (data $? ?)              (data green red)           Y

Multi-field wildcard and literal fields can be combined to provide very
powerful constructs. A pattern to match all the facts that have the word
YELLOW in any field (other than the first) could be written as:

   (data $? YELLOW $?)

Some examples of what this pattern would match are:

   (data YELLOW blue red green)
   (data YELLOW red)
   (data red YELLOW)
   (data YELLOW)
   (data YELLOW data YELLOW)

The last fact will match twice, since YELLOW appears twice in the fact. The
use of the multi-field wildcard should be confined to cases of patterns in
which the single-field wildcard cannot create a pattern that satisfies the
match required, since the multi-field wildcard produces every possible match
combination that can be derived from a fact. This derivation of matches
requires a significant amount of time to perform compared to the time needed
to perform a single-field match.

END-ENTRY

2IBEGIN-ENTRY-VARIABLES

LHS_SYNTAX
  VARIABLES

3.3 Variables- Single and Multi-field
Wildcard symbols replace portions of a fact pattern and accept any value. The
value of the field being replaced may be captured in a variable for
comparison, display, or other manipulations. This is done by directly
following the wildcard symbol with a variable name.

Syntax:

   ?<name>               ; a single value variable
   $?<name>              ; a multi-value variable

where <name> is a word, i.e. it must start with an alphabetic character, and
cannot include any spaces. Double quotes are not allowed as part of a
variable name, i.e. a string cannot be used for a variable name. The rules
for pattern matching are exactly the same as those for wildcard symbols. A
variable will bind the field's value(s) to that name from its first binding
until the end of all actions for that rule. The binding will only be true
within the scope of the rule in which it occurs. Each rule has its own
private list of variable names with their associated values: thus, variables
are local to a rule. The variables can be passed to external functions.

Examples:
   Pattern on LHS        Fact in the fact-list    ?x bound to:
   (data red ?x)         (data red green)         green
   (data red ?x)         (data red "green")       "green"

   Pattern on LHS        Fact in the fact-list   $?x bound to:      
   (data red $?x)        (data red)              -- nothing --
   (data red $?x)        (data red green)        (green)
   (data red $?x)        (data red "green")      ("green")
   (data red $?x)        (data red blue blue)    (blue blue)

   Pattern on LHS         Fact in the fact-list   ?x bound to:  ?y bound to: 
   (data ?x ?y)           (data red green)        red           green
   (data ?x ?y)           (data red "green")      red           "green"
   (data ?x ?y)           (data red green green)      --No match!--
   (data ?x ?y)           (data green red)        green         red


   Pattern on LHS         Fact in the fact-list   ?x bound to:  ?y bound to:
   (data ?x $?y)          (data red)              red           -nothing-
   (data ?x $?y)          (data red green)        red           green
   (data ?x $?y)          (data red "green")      red           "green"
   (data ?x $?y)          (data red blue blue)    red           blue, blue
   (data ?x $?y)          (data green red)        green         red

   Pattern on LHS         Fact in the fact-list    $?x bound to: ?y bound to:
   (data $?x ?y)          (data red)               nothing!      red
   (data $?x ?y)          (data red green)         red           green
   (data $?x ?y)          (data red "green")       red           "green"
   (data $?x ?y)          (data red blue blue)     red, blue     blue
   (data $?x ?y)          (data green red)         green         red

Once the initial binding of a variable occurs, all references to that same
variable have to match the same value that the first binding matched. This
applies to both single and multi-field variables. It also applies across
patterns.

 Single pattern examples:

   Pattern on LHS of rule Fact in the fact-list       Matches?
   (data ?x red ?x)       (data blue red blue)           Y
   (data ?x red ?x)       (data blue red get)            N
   (data ?x red ?x)       (data blue blue blue)          N
   (data ?x red ?x)       (data blue red "blue")         N

Multiple pattern examples:

   Patterns on LHS of rule Facts in the fact-list   Fires? 
   (defrule ..........
     (data red ?x)         (data red green)           Y
     (data purple ?x)      (data purple green)   
     => ......

   (defrule ..........
     (data red ?x)         (data red green)           N
     (data purple ?x)      (data purple blue)
     => ......

   (defrule ..........
     (data red $?x)        (data red blue green)      Y
     (data purple $?x)     (data purple blue green)   
      => ......

   (defrule ..........
     (data red $?x)        (data red blue green)      N
     (data purple $?x)     (data purple blue brown)
     => ......

END-ENTRY

2MBEGIN-ENTRY-CONSTRAINING_FIELDS

LHS_SYNTAX
  CONSTRAINING FIELDS

3.4 Constraining Fields
ib.Field constraints; are functions which constrain the range of values a
particular field within a pattern may have. There are two types of field
constraints: logical operators and predicate functions.

Subtopics :

    LOGICAL_OPERATORS     CONSTRAINING_FIELDS_THROUGH_PATTERN_EXPANSION
    PREDICATE_FUNCTIONS
    
END-ENTRY

3IBEGIN-ENTRY-LOGICAL_OPERATORS

LHS_SYNTAX
  CONSTRAINING FIELDS
    LOGICAL_OPERATORS

3.4.1 Logical Operators
There are three logical operators available for constraining values inside a
pattern. These are the logical operators:& (AND), logical operators:| (OR),
and logical operators:~ (NOT) operators. The logical operators can be
combined in almost any manner or number to constrain the value of specific
fields while pattern matching. Evaluation of multiple constraints can be
considered to occur from left to right.

Syntax:

   <value1>&<value2>   ; the AND operator
   <value1>|<value2>   ; the OR operator
   ~<value>            ; the NOT operator

The AND operator is typically used only in conjunction with the other logical
operators or variable bindings. Logical operators may be used along with
variable bindings.

More Syntax:

   ?x&<value1>|<value2>   ; the OR operator with variable
   ?x&~<value>            ; the NOT operator with variable

If this is the first occurrence of the variable name, then the field will be
constrained according to the logical operators only. The resulting value
will be stored in the variable. If the variable has been previously bound,
then it is considered an additional constraint along with the logical
operators, i.e. the field must have the same value already bound to the
variable and it must additionally match the constraints defined by the
logical operators.

Examples:

   Pattern on LHS of rule     Fact in the fact-list      Matches?    
   (data ~red)                (data red)                    N
   (data ~red)                (data green)                  Y

   (data red|blue)            (data red)                    Y
   (data red|blue)            (data blue)                   Y
   (data red|blue)            (data green)                  N

   (data ~red&~blue)          (data red)                    N
   (data ~red&~blue)          (data blue)                   N
   (data ~red&~blue)          (data green)                  Y

   (data ~red&blue|get)       (data red)                    N
   (data ~red&blue|get)       (data blue)                   Y
   (data ~red&blue|get)       (data get)                    Y
   (data ~red&blue|get)       (data green)                  N

Examples with variables/single patterns:

   Pattern on LHS     Fact in the fact-list   ?x bound to:    Matches?
   (data ?x&~red)     (data red)              ---                N
   (data ?x&~red)     (data green)            green              Y

   (data ?x&red|blue) (data red)              red                Y
   (data ?x&red|blue) (data blue)             blue               Y
   (data ?x&red|blue) (data green)            ---                N

Examples with variables/multiple patterns:

   Pattern on LHS     Fact in the fact-list   ?x bound to     Fires?
   (defrule .......   
     (data A ?x)      (data A red)            red                N
     (data B ?x&~red) (data B red)
     => ......

   (defrule .......   
     (data A ?x)      (data A red)            red                N
     (data B ?x&~red) (data B green) 
     => ......
 
   (defrule .......   
     (data A ?x)      (data A blue)           blue               Y
     (data B ?x&~red) (data B blue)
   => ......

   (defrule .......   
     (data A ?x)          (data A red)        red                Y
     (data B ?x&red|blue) (data B red)   
     => ......

   (defrule .......   
     (data A ?x)          (data A red)        red                N
     (data B ?x&red|blue) (data B blue)
     => ......

   (defrule .......   
     (data A ?x)          (data A green)      green              N
     (data B ?x&red|blue) (data B green)
     => ......

END-ENTRY

3IBEGIN-ENTRY-PREDICATE_FUNCTIONS

LHS_SYNTAX
  CONSTRAINING_FIELDS
    PREDICATE_FUNCTIONS

3.4.2 Predicate Functions
Sometimes it becomes necessary to constrain a field to more complex values
than can be defined by logic operators. CLIPS allows the use of predicate
functions to accomplish this. Predicate functions check to see if the value
of the field meets the constraints defined in the function. If it does, the
function returns true (non-zero) and pattern matching continues. Otherwise,
it returns false (0) and the pattern fails to match. Predicate functions are
called by combining the AND operator  with a colon (predicate functions:&:).
The value of the field must be bound to a variable and passed to the
function.

Syntax:

   ?x&:(<function> <<arguments>>)

Multiple predicate functions may be used to constrain a single field. They
are evaluated from left to right, each separated by an &: operator. Several
predicate functions are provided by CLIPS and users may also develop their
own predicate functions. Predicate functions operate on the value attempting
to be matched or may have arguments passed to them. The predicate functions
provided by CLIPS are:

   Function          Purpose
   (numberp <arg>)   Is the value a number?
   (evenp<arg>)      Is the value an even number?
   (oddp <arg>)      Is the value an odd number?
   (stringp <arg>)   Is the value a string?
   (wordp <arg>)     Is the value a word?

Examples:

   Pattern on LHS of rule               Fact in the fact-list   Matches?    
   (data ?x&:(numberp ?x))              (data 2)                   Y
   (data ?x&:(numberp ?x))              (data red)                 N

   (data ?x&:(numberp ?x)&:(oddp ?x))   (data 2)                   N

   (data ?x&:(stringp ?x))              (data 2)                   N
   (data ?x&:(stringp ?x))              (data red)                 Y

END-ENTRY

3IBEGIN-ENTRY-CONSTRAINING_FIELDS_THROUGH_PATTERN_EXPANSION

LHS_SYNTAX
  CONSTRAINING_FIELDS
    CONSTRAINING_FIELDS_THROUGH_PATTERN_EXPANSION

3.4.3 Constraining Fields Through Pattern Expansion
It is possible to use the return value of an external function to constrain
the value of a field. The equals (=) operator allows you to call external
functions from inside a pattern. The return value must be either a string, a
word, or a number. It is incorporated directly into the pattern at the
position the function was called, and any matching patterns must match this
value as though the rule were typed with that value.

Syntax:

   =(<function> <<args...>>

Example:

   Pattern on LHS     Function returns:   fact-list   Matches? 
   (data =(my_fun))   2                   (data 2)      Y
   (data =(my_fun))   2                   (data red)    N
   (data =(my_fun))   red                 (data 2)      N
   (data =(my_fun))   red                 (data red)    Y

Pattern expansion can also be used within variable bindings and combined with
other logical operators:

Pattern on LHS of rule            Facts in the fact-list      Matches? 
(defrule .....   
   (data ?y)                      (data 4)                      Y
   (data ?x&=(+ 5 ?y)|=(- 12 ?y)) (data 9)
   =>

END-ENTRY

2IBEGIN-ENTRY-USING_TEST_TO_CONSTRAIN_VARIABLES

LHS_SYNTAX
  USING_TEST_TO_CONSTRAIN_VARIABLES

3.5 Using test to Constrain Variables
The field constraint functions allow very descriptive constraints to be
applied to pattern matching. An additional constraint capability is provided
with the test function. As with predicate functions, you can compare the
variable bindings that have already occurred in any manner. You can do
mathematical comparisons on variables (e.g. is the difference between ?x and
?y greater than some value?), you can do complex logical or equality
comparisons, or you can call external functions which compare variables in
any way the user desires.

Any kind of external function may be embedded within a test operation (or
within field constraints). User defined predicate functions must take
arguments as defined in the Advanced Programming Guide and should return zero
(0) for false and a non-zero number for true. All defined functions use the
prefix notation, so the operands to a function always appear after the
function name. Several logical, comparison, and arithmetic functions are
provided by CLIPS. A complete list of CLIPS defined functions can be found in
Appendix A. 

Syntax:

   (test (<defined-function> [<<arguments>>]))

Functions within a test can be nested and are evaluated from the inside out.
The functions inherit their syntax and terminology from both LISP and C. The
predefined ones are:

Symbol    Function                       Use                Means
                            Logical
  !       not (inverse)                  logical            -
  &&      and                            logical            -
  ||      or                             logical            -

                           Comparison
  =       equal (numeric)                (test (= ?x ?y))   ?x = ?y
  eq      equal (any)                    (test (eq ?x ?y))  ?x eq ?y
  !=      not equal (numeric)            (test (!= ?x ?y))  ?x  ?y
  neq     not equal (any)                (test (neq ?x ?y)) ?x neq ?y
  >=      greater than or equal          (test (>= ?x ?y))  ?x >= ?y
  >       greater than                   (test (> ?x ?y))   ?x > ?y
  <=      less than or equal             (test (<= ?x ?y))  ?x <= ?y
  <       less than                      (test (< ?x ?y))   ?x < ?y

                           Arithmetic
  /       division                       (test (/ ?x ?y))   ?x / ?y
  *       multiplication                 (test (* ?x ?y))   ?x * ?y
  +       addition                       (test (+ ?x ?y))   ?x + ?y
  -       subtraction                    (test (- ?x ?y))   ?x - ?y

The comparison functions (=, !=, >=, etc) are only valid for comparing
numeric fields. When checking equality of strings, the eq and neq comparison
function should be used. eq and neq can compare strings or numbers and will
not produce an error when comparing a string to a number.

Examples:

The following example checks to see if the difference between ?y and ?x is
greater than three.


Patterns on LHS of rule    Fact in the fact-list    Fires? 
(defrule .....
   (data ?x)               (data 6)                  Y
   (value ?y)              (value 9)
   (test (>= (- ?y ?x) 3))
   =>  .....

The next example checks to see if there is a positive slope between two
points on a line.

Patterns on LHS of rule      Fact in the fact-list   Fires? 
(defrule .....
   (point ?a ?x1 ?y1)        (point 1 4.00 7.00)       Y
   (point ?b&~?a ?x2 ?y2)    (point 2 5.00 9.00)   
   (test (< 0 (/ (- ?y2 ?y1)
              (- ?x2 ?x1))))
   =>  .....

All defined functions may be used as predicates, although it is usually 
meaningful only for the comparison functions.

Examples/multiple patterns:

Patterns on LHS of rule       Fact in the fact-list     Fires? 
(defrule .....
   (data1 ?y)                (data1 3)                    Y
   (data2 ?x&:(> ?x ?y))     (data2 5)
   =>  .....

(defrule .....
   (data1 ?y)                (data1 9)                    N
   (data2 ?x&:(> ?x ?y))     (data2 5)
   =>  .....

(defrule .....
   (data1 ?y)                (data1 4)                    Y
   (data2 ?x&:(= ?y ?x))     (data2 4)   
   =>  .....

(defrule .....
   (data1 ?y)               (data1 red)                   N
   (data2 ?x&:(= ?x ?y))    (data2 5)             (this is an error!)  
   =>  .....


(defrule .....
   (data1 ?y)               (data1 "4")                   N
   (data2 ?x&:(= ?y ?x))    (data2 4)              (also an error!)
   =>  .....

These last two errors could be handled better as follows:

Patterns on LHS of rule      Fact in the fact-list      Fires? 
(defrule .....
   (data1 ?y&:(numberp ?y))  (data1 red)                  N
   (data2 ?x&:(= ?x ?y))     (data2 5)             (not an error)
   =>  .....

or, better still

(defrule .....
   (data1 ?y)                (data1 red)                  N
   (data2 ?x&:(eq ?x ?y))    (data2 5)             (not an error)
   =>  .....

END-ENTRY

2MBEGIN-ENTRY-CONSTRAINING_PATTERNS

LHS_SYNTAX
  CONSTRAINING_PATTERNS

3.6 Constraining Patterns
The LHS of CLIPS rules are made up of a series of patterns that represent the
conditions that must be satisfied in order for the rule to be placed on the
agenda. Unless otherwise noted, CLIPS assumes that all rules have an implicit
and surrounding the patterns on the LHS. This means that all conditions on
the LHS must be met before the rule can be activated. There is no need to
explicitly define an implicit and condition. However, it is possible to
change this default and define other logical combinations of conditions which
would cause a rule to fire. 

Logical pattern blocks allow patterns to be combined using inclusive or, and 
explicit and logic. The entire block is treated as a single condition on the
LHS and must be satisfied along with all other conditions before the rule can
fire. Logical blocks may be mixed with other logical blocks in any order and
patterns within the logical block may use field constraints. As with all
CLIPS features, the blocks are marked by opening and closing parentheses. 

Subtopics :

    INCLUSIVE_OR   PATTERN_NEGATION
    EXPLICIT_AND

END-ENTRY

3IBEGIN-ENTRY-INCLUSIVE_OR

LHS_SYNTAX
  CONSTRAINING_PATTERNS
    INCLUSIVE_OR

3.6.1 Inclusive or
The or logical block allows any one of several patterns to trigger a rule
firing. If any of the patterns inside the or block exist, the constraint is
satisfied. If all other LHS conditions are true, the rule will be activated.
Any number of patterns may be within an or block. The exact same effect could
be accomplished by writing multiple rules with similar left and right hand
sides.

Syntax:

   (defrule <name>
       [(<<additional patterns>>)]          
      (or (<<pattern 1>>) 
                .               
                .
         (<<pattern n>>))    
       [(<<additional patterns>>)]          
      =>             
      (<<actions>>))                

If more than one of the patterns in the or block can be met, the rule will
fire multiple times, once for each satisfied combination of conditions.

Example:

   (defrule system-fault
      (error-status unknown)
      (or (temp high)
         (valve broken)
         (pump off))
      =>         
      (printout "The system has a fault." crlf))
 
Note, the above example is exactly equivalent to the following three
(separate) rules:

   (defrule system-fault
      (error-status unknown)
      (pump off)
      =>         
      (printout "The system has a fault." crlf))

    (defrule system-fault
      (error-status unknown)
      (valve broken)
      =>         
      (printout "The system has a fault." crlf))
 
   (defrule system-fault
      (error-status unknown)
      (temp high)
      =>         
      (printout "The system has a fault." crlf))

END-ENTRY

3IBEGIN-ENTRY-EXPLICIT_AND

LHS_SYNTAX
  CONSTRAINING_PATTERNS
    EXPLICIT_AND

3.6.2 Explicit and
An explicit and is provided to allow the mixing of and and or conditions.
This allows logical combinations of patterns within an or block. The
constraint will be satisfied when all the patterns inside the explicit and
block are satisfied. If all other LHS conditions are true, the rule will be
activated. Any number of patterns may be placed in an and block. Any number
of ands may be within an or block.

Syntax:

   (defrule <name>
       [(<<additional patterns>>)]          
      (or   (and   (<<pattern 1>>) 
                   .
                   .
              (<<pattern n>>))
         (<<other patterns>>))   
       [(<<additional patterns>>)]          
      =>             
      (<<actions>>))                
 
Example:

   (defrule system-flow
      (error-status confirmed)
      (or   (and   (temp high)
            (valve closed))
         (and   (temp low)
            (valve open)))
      =>         
      (printout "The system is having a flow problem." crlf))

END-ENTRY

3IBEGIN-ENTRY-PATTERN_NEGATION

LHS_SYNTAX
  CONSTRAINING_PATTERNS
    PATTERN_NEGATION

3.6.3 Pattern Negation
Sometimes, the lack of information is meaningful, i.e. you wish to fire a
rule if a fact does not exist in the fact-list. The not function provides
this capability. As with logic blocks, any number of additional patterns may
also be on the LHS of the rule, and field constraints may be used within the
negated pattern.

Syntax:

   (defrule <name>
      (<<pattern 1>>)
      (not (<<pattern 2>>))
       [(<<additional patterns>>)]          
      =>             
      (<<actions>>)) 
      
Only one pattern may be negated at a time. Multiple patterns may be negated
by using multiple not statements. And and or logic blocks may not be placed
inside a not pattern, although a not may be placed inside an and or or. Care
must be taken when combining not with or and and blocks; the results aren't
always obvious! The same is true for variable bindings within a negated
pattern. Variables that are previously bound may be used freely inside a
negated pattern. However, variables bound for the first time within a negated
pattern can only be used in that pattern. Since negated patterns are treated
differently by CLIPS, users should always perform a reset after creating or
loading rules which include negated patterns.

Examples:

   (defrule high-flow-rate
      (temp high)
      (valve open)
      (not (error-status confirmed))
      =>
      (printout "Recommend closing of valve due to high temp" crlf))

   (defrule check-valve
      (check-status ?valve)
      (not (valve-broken ?valve))
      =>
      (printout "Device " ?valve " is OK" crlf))

   (defrule double-pattern
      (data red)
      (not (data red ?x ?x))
      =>
      (printout "No patterns with red green green!" crlf ))
 
Negating a not is illegal, i.e.  (not (not (<<pattern>>))) is not allowed.

END-ENTRY

2IBEGIN-ENTRY-PATTERN_BINDINGS

LHS_SYNTAX
  PATTERN_BINDINGS

3.7 Pattern Bindings
Certain RHS actions, such as retract, operate on an entire fact. To signify
which fact they are to act upon, a variable can be bound to an entire fact.

Syntax:

   ?<var-name><-(<<fields>>)

The left arrow, "<-", is a required part of the syntax.

Example:

   (defrule dummy
      (data 1)
      ?fact<-(dummy pattern)
      =>
      (retract ?fact))

END-ENTRY

2MBEGIN-ENTRY-DECLARING_RULE_PROPERTIES

LHS_SYNTAX
  DECLARING_RULE_PROPERTIES

3.8 Declaring Rule Properties
This feature allows properties or characteristics of a rule to be defined.
The characteristics are declared on the LHS of a rule using the declare
construct. A rule may have multiple declare constructs, but all declare
statements must appear before the first pattern on the LHS. The general
syntax is:

Syntax:

   (declare (<something> [<<args>>]))

Currently, there is only one declarative feature allowed; salience. Future
versions of CLIPS may provide more declarative capabilities and functions to
allow users to define their own declarative properties.

Subtopics :

    ASSIGNING_RULE_PRIORITY

END-ENTRY

3IBEGIN-ENTRY-ASSIGNING_RULE_PRIORITY

LHS_SYNTAX
  DECLARING_RULE_PROPERTIES
    ASSIGNING_RULE_PRIORITY

3.8.1 Assigning Rule Priority
A salience statement allows the user to assign a priority to a rule. When
multiple rules are in the agenda, the rule with the highest priority will
fire first.

Syntax:

   (declare (salience <num>))

where <num> must be an integer. If not specified, the salience value for a
rule defaults to zero. Salience values may be either positive or negative.
The largest allowed value is 10000. The smallest allowed value is -10000.

Example:

   (defrule test
      (declare (salience 99))    ; salience declaration
      (initial-fact)   ; matches the initial fact
      =>
      (printout "I Have a salience value of 99." crlf))

END-ENTRY

1MBEGIN-ENTRY-RHS_SYNTAX

RHS_SYNTAX

4.0 RHS Syntax - Actions
This section describes the various actions available on the RHS of rules. 

Subtopics :

  BASIC_ACTIONS          MATH_FUNCTIONS
  MULTI-FIELD_FUNCTIONS  ADDITIONAL_FUNCTIONS
  CLIPS_I/O_SYSTEM

END-ENTRY

2MBEGIN-ENTRY-BASIC_ACTIONS

RHS_SYNTAX
  BASIC_ACTIONS

4.1 Basic Actions
The following actions are the most commonly used RHS actions. They deal with
basic functions like asserting and retracting facts.

Subtopics :

    CREATING_NEW_FACTS                 BINDING_VARIABLES
    REMOVING_FACTS_FROM_THE_FACT-LIST  STOPPING_CLIPS
    ASSERTING_A_STRING

END-ENTRY

3MBEGIN-ENTRY-CREATING_NEW_FACTS

RHS_SYNTAX
  BASIC_FACTS
    CREATING_NEW_FACTS

4.1.1 Creating New Facts
The assert action allows you to add a fact to the fact-list. Only one fact
may be asserted in each assert statement. However, multiple asserts may be
placed on the RHS of a rule.

Syntax:

   (assert (<<pattern>>))

The fact asserted may contain bound variables, function calls, and literal
values. If an identical copy of the fact already exists in the fact-list, the
fact will not be added.

Examples:

   (assert (data red))   ; assert a simple fact

   (defrule close-valve
      (temp ?sensor high)
      (valve ?v open)
      (not (error-status confirmed))
      =>
      (assert  (Set ?v close))   ;assert a fact with variables
      (printout "Close valve due to high temp" crlf))

Subtopics :

      CALLING_EXTERNAL_FUNCTIONS

END-ENTRY

4IBEGIN-ENTRY-CALLING_EXTERNAL_FUNCTIONS

RHS_SYNTAX
  BASIC_ACTIONS
    CREATING_NEW_FACTS
      CALLING_EXTERNAL_FUNCTIONS

4.1.1.1 Calling External Functions
Sometimes it is preferable to call an external function from inside an
assert. The return value from the function is incorporated directly into the
pattern at the position the function was called. As with pattern expansion
on the LHS side of a rule, the equal operator (=) is used.

Syntax:

   (assert ([<<fields>>] =(<function> <<args...>>) [<<fields>>])

This is exactly the same as binding a variable to the return from a function
using the bind function and then placing the variable inside the assert.

Examples:

   (assert (data red =(+ ?x ?y)))

   (defrule user-close-valve
      (goal close valve)
      (input-from user)
      =>
      (printout "Which valve should be closed? ")
      (assert (close-valve =(read))))

END-ENTRY

3IBEGIN-ENTRY-REMOVING_FACTS_FROM_THE_FACT-LIST

RHS_SYNTAX
  BASIC_ACTIONS
    REMOVING_FACTS_FROM_THE_FACT-LIST

4.1.2 Removing Facts from the Fact-list
The retract action allows you to remove facts from the fact-list. Multiple
facts may be retracted with a single retract statement. The retraction of a
fact also removes all rules from the agenda that depended upon that fact for
activation.

Syntax:

   (retract ?<fact-var> [?<<fact-vars>>] | <fact-num> [<<fact-nums>>])

Facts may be identified either as fact variables (?<fact-var>) bound on the
LHS as described in LHS_SYNTAX PATTERN_BINDINGS, or by number (<fact-num>). 
Note that the number is generally not known during the execution of a program,
so facts are usually retracted by binding them on the LHS of a rule. External 
functions may not be called from retract.

Example:

   (defrule change-valve-status
      ?f1<-(valve ?v open)
      ?f2<-(Set ?v close)
      =>
      (retract ?f1 ?f2)
      (assert  (valve ?v close)))

END-ENTRY

3IBEGIN-ENTRY-ASSERTING_A_STRING

RHS_SYNTAX
  BASIC_ACTIONS
    ASSERTING_A_STRING

4.1.3 Asserting a String
The string_assert function is similar to assert in that it will add a fact to
the fact-list. However, string_assert takes a single string and breaks it
into separate fields prior to asserting the fact. Spaces, newlines, carriage
returns, or tabs within the string will be used as the delimiter between
fields. Like assert, only one fact may be asserted with each string_assert
statement.

Syntax:

   (string_assert <quoted-string>)

If an identical copy of the fact already exists in the fact-list, the fact
will not be added. Fields may contain a quoted string by escaping the quote
with a backslash. This functions is particularly effective when used with the
readline function (see RHS_SYNTAX CLIPS_I/O_SYSTEM COMMON_I/O_FUNCTIONS
READLINE). 

Examples:

   statement:                               asserted fact:
   (string_assert "status valve open")      (status valve open)
   (string_assert "light \"red\"")          (light "red")

END-ENTRY

3IBEGIN-ENTRY-BINDING_VARIABLES

RHS_SYNTAX
  BASIC_ACTIONS
    BINDING_VARIABLES

4.1.4 Binding Variables
Occasionally it is important to create new variables or modify the value of
previously bound variables on the RHS of a rule. The bind function provides
this capability.

Syntax:

   (bind ?<var-name>  <value> or <variable> or (<defined-function>))

Where <var-name> must be a variable name (it may have been previously bound).
<var-name> can be bound to literal values, other bound variables, or the
return from a function call.

Examples:

   (bind ?input (read))
   (bind ?value (+ ?x ?y))
   (bind ?value (+ (* ?y ?z) (* ?x ?z)))
   (bind ?new ?old)
   (bind ?number 14)

END-ENTRY

3IBEGIN-ENTRY-STOPPING_CLIPS

RHS_SYNTAX
  BASIC_ACTIONS
    STOPPING_CLIPS

4.1.5 Stopping CLIPS
The halt function may be used on the RHS of a rule to prevent further rule
firing. It is called without arguments. After halt is called, control is
returned to the top level program. The agenda is left intact, and execution
may be continued with a run command.

Syntax:

   (halt)

Example:

   (defrule halt-if-error
      (data ?x)
      =>
      (if (< (abs ?x) 0.00001)
      then
         (printout "Error, number to small" crlf)
         (halt)
      else
         (assert (new_data =(/ 15 ?x)))

END-ENTRY

2MBEGIN-ENTRY-MULTI-FIELD_FUNCTIONS

RHS_SYNTAX
  MULTI-FIELD_FUNCTIONS

4.2 Multi-field Functions
The following functions operate on multi-field variables.

Subtopics :

    NUMBER_OF_ELEMENTS     FINDING_AN_ELEMENT
    SPECIFYING_AN_ELEMENT

END-ENTRY

3IBEGIN-ENTRY-NUMBER_OF_ELEMENTS

RHS_SYNTAX
  MULTI-FIELD_FUNCTIONS
    NUMBER_OF_ELEMENTS

4.2.1 Number of Elements
The length function returns the number of elements bound to a multi-field
variable.

Syntax:

   (length <variable>)

where <variable> must be a multi-field variable ($?). If the variable is not
a multi-field variable, length returns a negative one (-1).

Example:

Given this fact in the database:   (data a b c d e f g)

   (defrule test-length
      (data $?a)
      =>
      (bind ?num (length $?a))
      (printout crlf "Length of data is " ?num))

The above rule prints:    Length of data is 7

END-ENTRY

3IBEGIN-ENTRY-SPECIFYING_AN_ELEMENT

RHS_SYNTAX
  MULTI-FIELD_FUNCTIONS
    SPECIFYING_AN_ELEMENT

4.2.2 Specifying an Element
The nth function will return a specified element from a multi-field variable.
It is similar in use to the LISP nth function.

Syntax:

   (nth <number> <variable>)

where <number> is an integer from 1 to the number of elements bound to the
variable. <variable> must be a multi-field variable ($?). The symbol nil will
be returned if <number> is greater than number of elements in the variable.


Example:

Given the following fact in the fact-list:  (data a b c d e f g)

   (defrule test-length
      (data $?a)
      =>
      (bind ?c (nth 3 $?a))
      (printout crlf "Third element in data is " ?c))

The above rule prints:   Third element in data is c

END-ENTRY

3IBEGIN-ENTRY-FINDING_AN_ELEMENT

RHS_SYNTAX
  MULTI-FIELD_FUNCTIONS
    FINDING_AN_ELEMENT

4.2.3 Finding an element
The memberfunction will tell if an atom is in a multi-value variable.

Syntax:

   (member <atom> $?<var>)

where <atom> can be either a literal value or a variable. <var> must be bound
to a multi-field variable. If <atom> is one of the values bound to <var>,
member will return the number of the element. otherwise it will return 0.

Examples:

Given the following fact in the fact-list: 
            (data red "green" blue brown)

   (defrule test-member
      (data $?a)
      =>
      (bind ?val (member blue $?a))
      (fprintout t "Blue is item " ?a " in the list" crlf))

The above rule prints: Blue is item 3 in the list

END-ENTRY

2MBEGIN-ENTRY-CLIPS_I/O_SYSTEM

RHS_SYNTAX
  CLIPS_I/O_SYSTEM

4.3 The CLIPS I/O System
CLIPS uses a system called I/O routing to provide very flexible I/O while
remaining portable. A more complete discussion of I/O routing is covered in
the Advanced Programming Guide.

Subtopics :

    LOGICAL_NAMES   COMMON_I/O_FUNCTIONS

END-ENTRY

3IBEGIN-ENTRY-LOGICAL_NAMES

RHS_SYNTAX
  CLIPS_I/O_SYSTEM
    LOGICAL_NAMES

4.3.1 Logical Names
One of the key concepts of I/O routing is the use of logical names. Logical
names allow reference to an I/O device without having to understand the
details of the implementation of the reference. Many functions in CLIPS make
use of logical names. A logical name can be either a word, a number, or a
string. Several logical names are predefined by CLIPS and used extensively
throughout the CLIPS code. These are:

Name        Description

wclips      The CLIPS prompt is sent to this logical name.
wdialog     All informational messages are sent to this logical name.
wdisplay    Requests to display CLIPS information, such as facts or rules are
            sent to this logical name.
werror      All error messages are sent to this logical name.
wtrace      All tracing (watch) information is sent to this logical name.
wagenda     When the agenda is displayed, it is sent to this logical name.
stdin       The default for all user inputs is this logical name.
stdout      All output from the printout function is sent to this logical name.

The format and fprintout functions send output to stdout if t is 
specified as the logical name.

Any of these logical names may be used anywhere a logical name is expected.

END-ENTRY

3MBEGIN-ENTRY-COMMON_I/O_FUNCTIONS

RHS_SYNTAX
  CLIPS_I/O_SYSTEM
    COMMON_I/O_FUNCTIONS

4.3.2 Common I/O Functions
CLIPS provides some of the most commonly needed I/O capabilities through
several pre-defined functions.

Subtopics :

      OPEN       PRINTOUT
      CLOSE      FPRINTOUT
      READ       FORMAT
      READLINE

END-ENTRY

4IBEGIN-ENTRY-OPEN

RHS_SYNTAX
  CLIPS_I/O_SYSTEM
    COMMON_I/O_FUNCTIONS
      OPEN

4.3.2.1 Open
The open function allows a user to open a file from the RHS of a rule and
attaches a logical name to it. This function takes three arguments: 1) the
name of the file to be opened, 2) the logical name which will be used by
other CLIPS I/O  functions to access the file, and 3) an optional mode
specifier. The mode specifier must be one of the following:

   Mode              Means
     r               read access only
     w               write access only
     r+              read and write access
     a               append access only
                                             
If the mode is not specified, a default of read access only is assumed. The
access mode may not be meaningful in some operating systems. 

Syntax:

   (open "<file-name>" <logical-name> ["<mode>"])

The <file-name> must be enclosed in double quotes and may include directory
specifiers. The backslash (\) and any other special characters that are part
of <file-name> must be escaped with a backslash. The logical name should not
have been previously used.

Examples:

   (defrule fileopen-test
      (initial-fact)
      =>
      (open "myfile.clp" myfiletag "r+"))
      (open "MS-DOS\\directory\\file.clp" file)

END-ENTRY

4IBEGIN-ENTRY-CLOSE

RHS_SYNTAX
  CLIPS_I/O_SYSTEM
    COMMON_I/O_FUNCTIONS
      CLOSE

4.3.2.2 Close
The close function closes a file stream previously opened with the open 
command. The file is specified by a logical name previously attached to the
desired stream.

Syntax:

   (close [<logical-name>])

If close is called without arguments, all open files will be closed.

Example:

   (defrule file-open
      (initial-fact)
      =>
      (open "test.clp" data-file))
      
               ; Other rules which use the file
      
   (defrule file-close
      (close-file data-file)
      =>
      (close data-file))

The user is responsible for closing all files opened during execution. If
files are not closed, the contents are not guaranteed to be correct.

END-ENTRY

4IBEGIN-ENTRY-READ

RHS_SYNTAX
  CLIPS_I/O_SYSTEM
    COMMON_I/O_FUNCTIONS
      READ

4.3.2.3 Read
The read function allows a user to input information for a single field.  All
the standard field rules (e.g. multiple words must be embedded within quotes)
apply. 

Syntax:

   (read [<logical-name>])

where <logical-name> is an optional parameter. If it is specified, read tries
to read from whatever is attached to the logical file name. If <logical-name>
is t or is not specified, the function will read from stdin.  If an end of
file is encountered while reading, read will return the word EOF. If errors
are encountered while reading, the string "*** READ ERROR ***" will be
returned.

Example:

   (defrule fileread
      (initial-fact)
      =>
      (open "data.clp" mydata)
      (bind ?input (read mydata))
      (assert (data ?input)))

END-ENTRY

4IBEGIN-ENTRY-READLINE

RHS_SYNTAX
  CLIPS_I/O_SYSTEM
    COMMON_I/O_FUNCTIONS
      READLINE

4.3.2.4 Readline
The readline function is similar to the read function, but it allows a whole
string to be input instead of a single field. Normally, read will stop when
it encounters a space, tab, carriage return or end of file. readline only
stops when it encounters a carriage return or end of file. Any tabs or spaces
in the input are returned by readline as a part of the string. readline
returns a quoted string.

Syntax:

   (readline [<logical-name>])

where <logical-name> is an optional parameter. If it is specified, readline
tries to read from whatever is attached to the logical file name. If
<logical-name> is t or is not specified, the function will read from stdin. 
As with read, if end of file is encountered, readline will return the word
EOF. If an error is encountered during input, readline  returns the quoted
string "*** READ ERROR ***".

Example:

   (defrule file-read-line
      (initial-fact)
      =>
      (open "data.txt" mydata)
      (bind ?input-string (readline mydata))
      (assert (data ?input-string)))

If the file "data.txt" had a first line as follows:

   the pretty red dog

the following fact will be asserted:

   (data "the pretty red dog")

END-ENTRY

4IBEGIN-ENTRY-PRINTOUT

RHS_SYNTAX
  CLIPS_I/O_SYSTEM
    COMMON_I/O_FUNCTIONS
      PRINTOUT

4.3.2.5 Printout
The printout function allows simple output to the standard output device 
(whatever is attached to stdout, usually the screen). It will evaluate
variable bindings and print the value of a variable in the output string. Any
number of items may be placed in a printout.

Syntax:

   (printout <item> ... <item> [crlf])

Where <item> is a bound variable, string, number, word, or function call. The
word crlf will force a carriage return/line feed and may be placed anywhere
in the list of items.

Example:

   (defrule change-valve-status
      ?f1<-(valve ?v open)
      ?f2<-(Set ?v close)
      =>
      (retract ?f1 ?f2)
      (assert  (valve ?v close))
      (printout "The valve " ?v " has been closed" crlf))

Note that the printout function is completely replaced by fprintout and
format. This function is still provided for compatibility with code written
in earlier releases of CLIPS.

END-ENTRY

4IBEGIN-ENTRY-FPRINTOUT

RHS_SYNTAX
  CLIPS_I/O_SYSTEM
    COMMON_I/O_FUNCTIONS
      FPRINTOUT

4.3.2.6 Fprintout
The fprintout function allows output to a device attached to a logical name.
The logical name MUST be specified and the device must have been previously
prepared for output (e.g. a file must be opened first). To send output to
stdout, use a t for the logical name. fprintout will evaluate variable
bindings and print the value of a variable in the output string. Any number
of items may be placed in an fprintout.

Syntax:

   (fprintout <logical-name> <item> ... <item> [crlf])

where <item> is a literal value, a bound variable, or a function call. As
with printout, the word crlf will force a carriage return/newline and may be
placed anywhere in the item list.

Example:

   (defrule change-valve-status
      ?f1<-(valve ?v open)
      ?f2<-(Set ?v close)
      =>      
      (open "out.clp" data "w")
      (retract ?f1 ?f2)
      (assert  (valve ?v close))
      ;; The next line sends output to the file
      (fprintout data "The valve " ?v " has been closed" crlf)
      (fprintout data "Example with \"quoted\" information" crlf)
      ;; The next line sends output to standard out
      (fprintout t "Data written." crlf))

END-ENTRY

4IBEGIN-ENTRY-FORMAT

RHS_SYNTAX
  CLIPS_I/O_SYSTEM
    COMMON_I/O_FUNCTIONS
      FORMAT

4.3.2.7 Format
The format function allows a user to send formatted output to a device
attached to a logical name. It can be used in place of fprintout, when
special formatting of output information is desired. The format commands are
similar to the printf statement in C.

Syntax:

   (format <logical-name> "<control-string>" <<parameter-list>>)

where <logical-name> is any logical name. If it is t, then output is sent to
stdout. The <control-string> is a quoted string which specifies how the
output should be formatted. The <<parameter-list>> are the bound variables or
literal values which are to be output.  Function calls may also be embedded
in the <<parameter-list>> and the return from the function will be output.
Format currently does not support multi-field variables in the
<<parameter-list>>.

The control string consists of text and format flags. The text is output
exactly as specified and the format flags describe how each parameter in the
<<parameter-list>> is to be formatted. The first format flag corresponds to
the first value in the parameter list, the second flag corresponds to the
second value, and so on. The format flags must be preceded by a percent sign
(%) and are of the general format:

   %-M.Nx

where x is one of the flags listed below, the minus sign is an optional
justification flag, and M and N are optional parameters which specify the
field width and number of digits following the decimal place. If M is used,
at least M characters will be output. If more than M characters are required
to display the value, then format expands the field as needed. If M starts
with a 0 (e.g. %07d) then a zero is used as the pad character, otherwise
spaces are used. If N is not specified, it defaults to six digits for
floating point numbers. If a  minus sign is included before the M, the value
will be left justified, otherwise the value is right justified. 

Format Flags:
   d   :   Display parameter as an integer.
          (The N specifier has no meaning)

   f   :   Display parameter as a floating-point number.

   e   :   Display parameter as a floating-point using power of ten          
           notation. 
   g   :   Display parameter in the most general format, whatever is         
           shorter. 

   o   :   Display parameter as an unsigned octal number.
           (The N specifier has no meaning)

   x   :   Display parameter as an unsigned hexidecimal number.
          (The N specifier has no meaning)

   s   :   Display parameter as a string. Quoted strings will have the       
           leading and trailing quotes stripped.
          (The N specifier has no meaning. Also, zero can not be used       
                for the pad character)

   n   :   Put a carriage return/line feed in the output

   %   :   Put the percent character into the output

Examples:

Given the following variable bindings:

   ?num   = 12
   ?float   = 12.01
   ?str1   = valve-A1
   ?str2   = "capacity"

      format statement            Gives

   (format t "Test:%d" ?num)      Test:12
   (format t "Test:%4d" ?num)     Test:  12
   (format t "Test:%04d" ?num)    Test:0012
   (format t "Test:%-04d" ?num)   Test:1200
   (format t "Test:%d" ?float)    Test:12

   (format t "Test:%f" ?num)      Test:12.000000
   (format t "Test:%f" ?float)    Test:12.010000
   (format t "Test:%7f" ?num)     Test:12.000000
   (format t "Test:%7.2f" ?num)   Test:  12.00
    (format t "Test:%07.2f" ?num) Test:0012.00

   (format t "Test:%e" ?num)      Test:1.200000e+01
   (format t "Test:%7e" ?num)     Test:1.200000e+01
   (format t "Test:%7.2e" ?num)   Test:1.20e+01
   (format t "Test:%07.2e" ?num)  Test:1.20e+01
   (format t "Test:%011.2e" ?num) Test:0001.20e+01

   (format t "Test:%g" ?num)      Test:12
   (format t "Test:%g" ?float)    Test:12.01
   (format t "Test:%g" 1234567890)Test:1.234568e+09

   (format t "Test:%o" ?num)      Test:14
   (format t "Test:%x" ?num)      Test:c

   (format t "Test:%s" ?str1)     Test:valve-A1
   (format t "Test:%s" ?str2)     Test:capacity

   (format t "The %s is at %d%% of its \"%s\"" ?str1 ?num ?str2)

gives

   The valve-A1 is at 12% of its "capacity"

Portability Note

The format function uses the C function sprintf as a base. Some systems may
not support sprintf or may not support all these features, which may affect
how format works.

END-ENTRY

2MBEGIN-ENTRY-MATH_FUNCTIONS

RHS_SYNTAX
  MATH_FUNCTIONS

4.4 Math Functions
CLIPS provides several functions for mathematical computations. They are
split into two packages, a set of standard math functions and a set of
extended math functions.

Subtopics :

    STANDARD_MATH_FUNCTIONS   EXTENDED_MATH_FUNCTIONS

END-ENTRY

3IBEGIN-ENTRY-STANDARD_MATH_FUNCTIONS

RHS_SYNTAX
  MATH_FUNCTIONS
    STANDARD_MATH_FUNCTIONS

4.4.1 Standard Math Functions
The standard math functions include add, subtract, multiply, and divide.
These functions should only be used on numeric arguments. An error message
will be printed during execution if a string argument is passed to a math
function.

Examples:

   divide     (bind ?var (/ ?x ?y))   ; means ?var = ?x / ?y
   multiply   (bind ?var (* ?x ?y))   ; means ?var = ?x * ?y
   add        (bind ?var (+ ?x ?y))   ; means ?var = ?x + ?y
   subtract   (bind ?var (- ?x ?y))   ; means ?var = ?x - ?y

Arithmetic function calls can be used anywhere an external function is valid.

END-ENTRY

3IBEGIN-ENTRY-EXTENDED_MATH_FUNCTIONS

RHS_SYNTAX
  MATH_FUNCTIONS
    EXTENDED_MATH_FUNCTIONS

4.4.2 Extended Math Functions
In addition to the standard math functions, CLIPS also provided a large number
of scientific and trigonometric math functions for more extensive computations.
Although included in the generic version of CLIPS, if an expert system does not
need these capabilities, these functions may be excluded from the executable
element of CLIPS to provide more memory (see the Advanced Programming Guide).
The following functions all take one argument:

General Syntax:

   (<fun> <arg>)

Example:

   (defrule trigtest
      (number ?x)
      =>
      (bind ?y (cos ?x))

Function   Returns:

cos        cosine
sin        sine
tan        tangent
sec        secant
csc        cosecant
cot        cotangent
acos       arccosine
asin       arcsine
atan       arctangent
asec       arcsecant
acsc       arccosecant
acot       arccotangent
cosh       hyperbolic cosine
sinh       hyperbolic sine
tanh       hyperbolic tangent
sech       hyperbolic secant
csch       hyperbolic cosecant
coth       hyperbolic tangent
acosh      hyperbolic arccosine
asinh      hyperbolic arcsine
atanh      hyperbolic arctangent
asech      hyperbolic arcsecant
acsch      hyperbolic arccosecant
acoth      hyperbolic arccotangent

   (NOTE: All the trigonometric functions expect RADIAN arguments)

log        log base e
log10      log base 10
exp        e**<arg>
sqrt       square root
trunc      truncates argument to integer
deg-rad    convert from degrees to radians
rad-deg    convert from radians to degrees
abs        absolute value

The following functions take multiple arguments:

Function   # of arguments   Returns:

min        1 or more        min value of all args
max        1 or more        max value of all args
pi         none             the value of pi
mod        2                modulus of arg1 by arg2
**         2                arg1 raised to the arg2 power


Portability Note

These mathematical functions use the C library math.h. If your system does
not support this library, you need to make some adjustments to math.c. The
system dependent math functions are called from clcos,  clsin, and so on.
You must change each of these to call the appropriate functions from your
system. Make sure that the functions clcos, clsin, etc. always return
FLOATING point numbers. To link these functions, most compilers provide a
separate math library which must be included during linking.

END-ENTRY

2MBEGIN-ENTRY-ADDITIONAL_FUNCTIONS

RHS_SYNTAX
  ADDITIONAL_FUNCTIONS

4.5 Additional Functions
The following are additional functions for use on the RHS of CLIPS rules.

Subtopics :

    SYSTEM   IF...THEN...ELSE
    GENSYM   WHILE
    SETGEN   STRING_CONCATENATION
    CALL     USING_CLIPS_INTERFACE_COMMANDS

END-ENTRY

3IBEGIN-ENTRY-SYSTEM

RHS_SYNTAX
  ADDITIONAL_FUNCTIONS
    SYSTEM

4.5.1 System
The system function allows a call to the operating system. It is patterned
after the system function provided to C on most UNIX systems. 

Syntax:

   (system <<args>>)

Example:

   (defrule print-directory
      (print-directory  ?directory)
      =>
      (system "dir " ?directory))   ; Note space => "dir<space>"

Note that any spaces needed for proper parsing of the system command must be 
added by the user in the call to system.

Portability Note

Not all operating systems/compilers provide this function. The code is stored
in the sysdep.c file and the default coding for generic CLIPS is a
non-functional stub which will compile on any machine.

END-ENTRY

3IBEGIN-ENTRY-GENSYM

RHS_SYNTAX
  ADDITIONAL_FUNCTIONS
    GENSYM

4.5.2 Gensym
The gensym function returns a special, sequenced word, which can be stored as
a single field. This is primarily for tagging patterns which need a unique
identifier but the user doesn't care what the identifier is. Multiple calls
to gensym are guaranteed to return different identifiers of the form:

            genX

where X is a positive integer. The first call to gensym returns gen1, all
subsequent calls increment the number. If users plan to use the gensym
feature, they should avoid creating facts which include a user defined field
of this form.

Example:

   (assert (new-id  =(gensym) flag1 7))

which, on the first call, generates a fact of the form:

   (new-id gen1 flag1 7)

END-ENTRY

3IBEGIN-ENTRY-SETGEN

RHS_SYNTAX
  ADDITIONAL_FUNCTIONS
    SETGEN

4.5.3 Setgen
The setgen function allows the user to set the starting number used by  
gensym (see RHS_SYNTAX ADDITIONAL_FUNCTIONS GENSYM).

Syntax:

   (setgen <num>)

where <num> must be a positive integer value. All subsequent calls to gensym
will return a sequenced word with the numeric portion of the word starting at
<num>.

Example:

   (setgen 32)

After this, calls to gensym will return  gen32, gen33, etc.

END-ENTRY

3IBEGIN-ENTRY-CALL

RHS_SYNTAX
  ADDITIONAL_FUNCTIONS
    CALL

4.5.4 Call
Previous versions of CLIPS provided access to external functions through the
call syntax. Version 4 of CLIPS allows external functions to be called
directly from the RHS. To provide compatibility with code written for earlier
versions, call is still available. Arguments may be passed to the external
function as described in the Advanced Programming Guide.

Syntax:

   (call (<function-name> [<<args...>>]))

Functions called in this manner must be called for effect only. The return
value will not be captured.

Example:

    (defrule display-valve-system
      (valve ?v1 open)
      (valve ?v2&~v1 closed)
      =>
      (call (display-valves ?v1 ?v2)))

END-ENTRY

3IBEGIN-ENTRY-IF...THEN...ELSE

RHS_SYNTAX
  ADDITIONAL_FUNCTIONS
    IF...THEN...ELSE

4.5.5 If...then...else
Under certain circumstances, it is preferable to take actions based on
parameter testing on the RHS of a rule instead of writing two or more rules.
CLIPS provides an if...then...else structure to allow this kind of operation.

Syntax:

   (if (<predicate-function> [<<args...>>])
    then
      (<<action 1>>)
         
      (<<action n>>)
   [else
      (<<action 1>>)
         
      (<<action n>>)])

Any number of allowable RHS actions may be used inside the then or else
section, including another if...then...else structure. The else portion is
optional. All predicate functions are available for use in this structure and
are used as they are in test. Variables used in the comparison must have been
previously bound.
Example:
   (defrule closed-valves
      (temp high)
      (valve ?v closed)
      =>
      (if (= ?v 6)
       then
         (printout "The special valve " ?v " is closed!" crlf)
         (assert (perform special operation))
       else
         (printout "Valve " ?v " is normally closed" crlf)))

Note that this rule could just as easily have been accomplished with two
rules, and it is usually better to do so.

   (defrule closed-valves-number-6
      (temp high)
      (valve 6 closed)
      =>
      (printout "The special valve 6 is closed!" crlf)
      (assert (perform special operation)))

   (defrule closed-valves-other-than-6
      (temp high)
      (valve ?v&~6 closed)
      =>
      (printout "Valve " ?v " is normally closed" crlf)))

END-ENTRY

3IBEGIN-ENTRY-WHILE

RHS_SYNTAX
  ADDITIONAL_FUNCTIONS
    WHILE

4.5.6 While
The while structure is provided to allow simple looping on the RHS of a rule.
Its use is similar to that of if...then...else:

Syntax:

   (while (<predicate-function> [<<args...>>])
      (<<action 1>>)
         
      (<<action n>>))

Again, all predicate functions are available for use in while. Any number of
allowable RHS actions may be placed inside the while block, including
if...then...else or additional while structures. The test is performed prior
to the first execution of the loop.

Example:

   (defrule open-valves
      (valves-open-through ?v)
      =>
      (while (> ?v 0)
         (printout "Valve " ?v " is open" crlf)
         (bind ?v (- ?v 1))))

END-ENTRY

3IBEGIN-ENTRY-STRING_CONCATENATION

RHS_SYNTAX
  ADDITIONAL_FUNCTIONS
    STRING_CONCATENATION

4.5.7 String Concatenation
The str_cat function will concatenate words or quoted strings and returns a
single quoted string.

Syntax:

   (str_cat <item1> <<items>>)

Each item must be a word, a string, a variable bound to either a word or a
string, or a function which returns a word or a string. Numbers are not
allowed.

Example:

   (bind ?new (str_cat "foo" bar))

gives

     ?new = "foobar"

END-ENTRY

3IBEGIN-ENTRY-USING_CLIPS_INTERFACE_COMMANDS

RHS_SYNTAX
  ADDITIONAL_FUNCTIONS
    USING_CLIPS_INTERFACE_COMMANDS

4.5.8 Using CLIPS Interface commands
Most of the commands documented in USING_CLIPS ENVIRONMENT_COMMANDS as part of
the CLIPS interactive interface are available on the RHS of a rule. They may be
called just like any other action. The exceptions are the run, reset, clear and
excise commands. These should not be called from the RHS of a rule. The
consequences are unpredictable. See ENVIRONMENT_COMMANDS for descriptions of the
available commands.

END-ENTRY

1MBEGIN-ENTRY-USING_CLIPS

USING_CLIPS

5.0 Using CLIPS
CLIPS expert systems may be executed in two ways; interactively using a
simple, line type interface, or as embedded expert systems in which the user
provides a main program and controls execution of the expert system. Embedded
applications are discussed in the Advanced programming Guide. 

CLIPS provides a simple, interactive, line type interface for high
portability. The standard usage is: Create or edit rules using any standard
text editor and save the file(s) as a text file. Exit the editor and execute
CLIPS. Load rule file(s) into CLIPS. The interface provides commands for
viewing the current state of the system, tracing execution, adding or
removing information, or clearing CLIPS.

Subtopics :

  ENVIRONMENT_COMMANDS     MEMORY_MANAGEMENT_COMMANDS
  SYSTEM_STATUS_COMMANDS   ADDITIONAL_COMMANDS
  DEBUGGING_COMMANDS

END-ENTRY

2IBEGIN-ENTRY-ENVIRONMENT_COMMANDS

USING_CLIPS
  ENVIRONMENT_COMMANDS

5.1 Environment Commands
The following commands control the CLIPS environment:

(reset)   Resets CLIPS. Removes all activations from the agenda 
and all facts from the fact-list, then asserts all facts listed in 
deffacts statements into the fact-list.

(clear)   Removes all rules and deffacts from the environment.  
Removes all activations from the agenda and all facts from 
the fact-list.

(run [<limit>])   Starts execution of the rules. If <limit> is positive,
execution will cease after <limit> rule firings or when the agenda 
contains no rule activations. If <limit> is not specified, or is 
a negative integer, execution will cease when the agenda 
contains no rule activations.

   Example:   (run 3)

(load <file-name>)   Loads the rules stored in the file specified by 
<file-name> into the environment.

   Example:    (load "rules.txt")

(save <file-name>)   Saves all of the rules in the current environment into 
the file specified by <file-name>.

   Example:    (save "rules.txt")

END-ENTRY

2IBEGIN-ENTRY-SYSTEM_STATUS_COMMANDS

USING_CLIPS
  SYSTEM_STATUS_COMMANDS

5.2 System Status Commands
The following commands display the current CLIPS status:

(facts)           Displays all facts stored in the fact-list.

(rules)           Displays the names of all rules stored in the database.

(agenda)          Displays all activations on the agenda.

(pprule <rule>)   Displays the text of the rule named <rule>.
   Example:  (pprule bogus-name)

(list-deffacts)   Displays the names of all deffact blocks currently loaded 
                  in CLIPS.

(ppdeffact <ID>)  Displays the text of a the deffacts block named <ID>.

END-ENTRY

2IBEGIN-ENTRY-DEBUGGING_COMMANDS

USING_CLIPS
  DEBUGGING_COMMANDS

5.3 Debugging Commands
The following commands control the CLIPS debugging aids:

(watch <item>)   If <item> is facts, all fact assertions and retractions will
                 be displayed.  If <item> is rules, all rule firings will be 
                 displayed.  If <item> is activations, all rule activations and 
                 deactivations will be displayed. If <item> is all, then 
                 facts, rules and activations will all be displayed.

                 Example:  (watch rules)

(unwatch <item>)   Deactivates the watch command for <item>. 

                   Example:  (unwatch rules)

(matches <rule>)   Displays a list of the facts which match each pattern on
                   the LHS of the rule, and the combinations, if any.

(dribble-on <file>)   Sends all watch information to <file>.

(dribble-off)   Stop sending watch information to a file.

END-ENTRY

2IBEGIN-ENTRY-MEMORY_MANAGEMENT_COMMANDS

USING_CLIPS
  MEMORY_MANAGEMENT_COMMANDS

5.4 Memory Management Commands
The following commands display CLIPS memory status information. 

(mem-used)   Display the number of bytes CLIPS has used since CLIPS 
             was started.

(release-mem)   Releases all free memory CLIPS is holding internally back 
                to the operating system.

(conserve-mem)   Turns off storage of pretty print information. This can save
                 considerable memory in a large system. It should be called
                 prior to loading any rules.

These functions generally should not be called unless you know exactly what
you are doing. CLIPS memory management is more fully described in the
Advanced Programmers Guide.

END-ENTRY

2IBEGIN-ENTRY-ADDITIONAL_COMMANDS

USING_CLIPS
  ADDITIONAL_COMMANDS

5.5 Additional Commands
The following commands are also available:

(assert <fact>)   Asserts <fact> into the database.

                  Example:  (assert (this is a fact))

(retract <<fact#>>)   Retracts the fact(s) with number(s) <<fact#>> from the 
                      database.   

                      Example:    (retract 4)  or  (retract 3 24 7)

(excise <rule>)   Remove the rule named <rule> from the system.

(undeffacts <name>)   Reverse the effect of a deffacts statement. All facts
                      listed in the deffacts construct named <name> will no 
                      longer be put into the initial fact-list after a reset.

(batch <file>)   Allows "batch" processing of CLIPS interactive commands. 
                 Processes all commands stored in <file> as though they had 
                 been entered at the top level. All interface commands can be
                 used in a batch file, including rule definitions and responses
                 to read or readline calls. Full error checking will not be 
                 done on rules defined in this manner (load is better for 
                 adding rules to the system).

                 Example:   

                 (batch "rules.bat") 
                    where "rules.bat" contains a number of load commands which
                 will cause all rules to be loaded.

(<name> [<<args>>])   Any function, user defined or CLIPS defined, may be 
                      called directly from the top level.

                      Example:   (system "dir")

(defrule <<rule>>)   Define a new rule, as described in CLIPS_OVERVIEW
                     DEFINING_CONSTRUCTS DEFINING_RULES.

(deffacts <<facts>>)   Define a new deffacts block, as described in 
                       DEFINING_INITIAL_FACTS.

As mentioned in USING_CLIPS_INTERFACE_COMMANDS, all of these commands can also
be called from the RHS of a rule, except the run, reset, excise, or clear
commands.

END-ENTRY

1MBEGIN-ENTRY-APPENDICES

APPENDICES

  DEFINED_FUNCTIONS      GLOSSARY
  VERSION_DIFFERENCES    ERROR_MESSAGES

END-ENTRY

2IBEGIN-ENTRY-DEFINED_FUNCTIONS

APPENDICES
  DEFINED_FUNCTIONS

The following table lists all the defined functions provided by CLIPS along
with examples of their use.

 Symbol     Function                Use                 Means
                        Logical

   !        not (inverse)           logical                -
   &&       and                     logical                -
   ||       or                      logical                -

                       Comparison

   =        equal (numeric)         (test (= ?x ?y))    ?x = ?y
   eq       equal (any)             (test (eq ?x ?y))   ?x eq ?y
   !=       not equal (numeric)     (test (!= ?x ?y))   ?x  ?y
   neq      not equal (any)         (test (neq ?x ?y))  ?x neq ?y
   >=       greater than or equal   (test (>= ?x ?y))   ?x >= ?y
   >        greater than            (test (> ?x ?y))    ?x > ?y
   <=       less than or equal      (test (<= ?x ?y))   ?x <= ?y
   <        less than               (test (< ?x ?y))    ?x < ?y

                       Arithmetic

   /        division                (test (/ ?x ?y))    ?x / ?y
   *        multiplication          (test (* ?x ?y))    ?x * ?y
   +        addition                (test (+ ?x ?y))    ?x + ?y
   -        subtraction             (test (- ?x ?y))    ?x - ?y

                       Predicate

   Function          Use                      Means

   (numberp <arg>)   (foo ?x&:(numberp ?x))   Is the value a number?
   (stringp <arg>)   (foo ?x&:(stringp ?x))   Is the value a string?
   (wordp <arg>)     (foo ?x&:(wordp ?x))     Is the value a word?
   (evenp <arg>)     (foo ?x&:(evenp ?x))     Is the value an even number?
   (oddp <arg>)      (foo ?x&:(oddp ?x))      Is the value an odd number?

= and !=  are for comparisons between numbers
eq and neq are for any kind of comparisons

END-ENTRY

2IBEGIN-ENTRY-VERSION_DIFFERENCES

APPENDICES
  VERSION_DIFFERENCES

Version 4.0
There have been many changes to CLIPS between the initial release, version
3.0, and this release, version 4.0. The primary differences are: 

   Improved performance - Almost all applications will see some performance 
improvement using version 4.0 of CLIPS. Some applications  will run up to
100% faster.

   Addition of numerous new functions - This version of CLIPS includes 
numerous new functions that allow file I/O, access to the underlying operating
system (on some machines), and makes the extended math package a standard
feature.
   Easier integration of custom I/O - The I/O router system makes integration
of specialized interfaces considerably easier.

   Easier installation - The CLIPS source code has considerably "cleaned up" 
and is better documented internally. Compiler directives allows better use of
machine dependent features. Some features can be selected or left out by
setting compiler flags.

None of these changes will affect code written under earlier releases. Great
care has been taken to insure that CLIPS is upwardly compatible. 

Minor Changes

Two functions from version 3.0 are no longer needed: printout, and call. The
printout function has been replaced by fprintout and format, which are
compatible with the I/O router system. The call function is no longer needed,
since user functions can be called directly from the top level or from the
RHS of a rule. Both these functions are still available to allow
compatibility with existing CLIPS code. To insure future compatibility and
efficient performance, old code should be changed to the new syntax.

The exponentiation function, **, has been moved from the standard math
package to the extended math package.

The predicate function stringp works slightly differently. Previously it
returned true if the argument was either a word or a string. Now it returns
false if the argument is a word. The wordp function has been added to allow
checking for variable of type word.

The function define_function which is used to add user defined functions to
CLIPS (see the Advanced Programming Guide) now takes four arguments instead
of three. The fourth argument is a string variable containing the name of the
external function. Code that calls define_function with only three arguments
should still work, but ought to be changed for compatibility of future
versions of CLIPS.

END-ENTRY

2IBEGIN-ENTRY-GLOSSARY

APPENDICES
  GLOSSARY

This section defines some of the terminology used throughout this manual. 

action   Any of a number of functions which can occur on the RHS of 
         a rule (see RHS_SYNTAX).

activation   A rule is activated if all it's conditions are satisfied and it
             is ready to fire. An activated rule is placed on the agenda.

agenda   The agenda is a list of all the rules that are presently ready to 
         fire. It is sorted by salience values. When a rule is activated, 
         it is placed in front of all the rules that have salience values 
         less than or equal to its own. The rule at the front of the 
         agenda is the next rule that will fire.

conditions   A set of patterns on the LHS of a rule which must all be 
             satisfied before a rule can fire.

external function   A function defined by the user or provided by CLIPS and 
                    called from within CLIPS rules.

fact   A set of words, strings or numbers separated by spaces. 
       Facts can have any number of fields and can be in any 
       order. Facts are the data which the expert system reasons 
       about. They represent the current state of the world.

field   A single word, string or number in a pattern or fact.

fire   A rule is said to have fired if all it's conditions are satisfied 
       and the actions are then executed.

instantiated   The pattern or variable has matched successfully against a 
               fact or field in the current fact-list.

LHS   Left Hand Side: The logical pattern structure that must be 
      satisfied in order for the RHS's actions to be performed. 

number   Any field which consists only of numbers (0-9), a decimal 
         point (.), a sign (+ or -), and/or an (e) for exponential notation
   
pattern   A conditional element on the LHS of a rule which is intended 
          to match elements in the fact-list.

RHS   Right Hand Side: The actions to be performed when a rule's 
      LHS is satisfied.  

rule   A collection of conditions and actions. When all patterns are 
       satisfied, the actions will be taken. Rules are the basic unit of 
       knowledge in CLIPS.

salience   A priority number given to a rule.  When multiple rules are 
           ready for firing, they are fired in order of priority. The default 
           salience is zero (0).  Rules with the same salience are fired 
           in arbitrary order.

special character   Any printable character (ASCII codes 32 through 127).

string   A set of characters that starts with a double quotes (") and is 
         followed by one or more letters (A-z), numbers (0-9), underscores(_),
         dashes (-), spaces, or special characters. A string 
         also ends with double quotes.

word   Any set of characters that starts with an alphabetic character 
       and is followed by zero or more letters (A-z), numbers (0-9), 
       underscores(_), or dashes (-).

END-ENTRY

2MBEGIN-ENTRY-ERROR_MESSAGES

APPENDICES
  ERROR_MESSAGES

CLIPS typically will display two kinds of error messages those associated
with function execution during run-time, and those associated with parsing
while loading rules. This appendix describes some of the more common error
messages and what they mean.

Subtopics :

    RUN-TIME_ERRORS    RULE_PARSING_ERRORS

END-ENTRY

3IBEGIN-ENTRY-RUN-TIME_ERRORS

APPENDICES
  ERROR_MESSAGES
    RUN-TIME_ERRORS

F.1 Run-time Error Message

--Function <name> expected <number> arguments

This error occurs when a function is not passed exactly  the number of
arguments it expects. The function is <name> and the number of arguments it
expected is <number>.


--Function <name> expected at least <number> arguments

This error occurs when a function is passed fewer arguments than it expected.
The function is <name> and the number of arguments it expected is <number>.


--Function <name> expected no more than <number> arguments

This error occurs when a function is passed more arguments than it needs. The
function is <name> and the number of arguments it expected is <number>.


--Function <name> expected argument #<number> to be of type <type>

rfloat received a request from function <name> for argument #<number> which
is not a number

rstring received a request from function <name> for argument #<number> which
is not a string

These errors occur when a function is passed the wrong type of argument,
typically a string or word when expecting a number, or vice versa.


rfloat received a request from function <name> for argument #<number> which
is non-existent

rstring received a request from function <name> for argument #<number> which
is non-existent

runkown received a request from function <name> for argument #<number> which
is non-existent

These errors occur when a function is passed fewer arguments than it
expected.

END-ENTRY

3IBEGIN-ENTRY-RULE_PARSING_ERRORS

APPENDICES
  ERROR_MESSAGES
    RULE_PARSING_ERRORS
 
F.2 Rule Parsing Error Message
Most parsing errors occur when loading the rules from a file or typing them
in from the top level interface. If loading them into the CLIPS interactive
interface, CLIPS will attempt to display the error message along with the
rule to demonstrate where the error occurred.  Although the error messages
attempt to provide meaningful information, it may be more useful to look at
the point at which parsing of the rule stopped.

--Missing a rule name!

This error occurs when a rule construct does not have a name.


--A pattern begins with '(' or ?<var>

This error occurs when a pattern construct on the LHS of a rule does not have
an opening parenthesis or variable.


--LHS of rule <name> contains no patterns only

This error occurs when a rule has no conditions


--Only a single pattern may appear after a not

This error occurs when multiple patterns are placed inside a not construct.


--Found <token> when expecting => in <rule>

This error occurs when a RHS action such as bind or fprintout is found before
the =>.


--Expected ')' to finish a rule

This error occurs when the final closing parenthesis is left off a rule.


--Missing <- after ?<var> in the LHS of <rule>

This error occurs when attempting to bind a pattern to a variable, but the
left arrow is forgotten.


--Missing '(' after ?<var> in the LHS of <rule>

This error occurs when attempting to bind a pattern to a variable, but the
opening parenthesis is forgotten.


--Missing closing ')' for test construct in <rule>

This error occurs when a closing parenthesis is left out of a test block.


--Missing '(' after logical pattern operator in <rule>

This error occurs when an opening parenthesis is left out of an and or or
construct.


--Unexpected token <token> found in the LHS of <rule>

This error occurs when a RHS action such as bind or fprintout are found on
the LHS of a rule.


--Expected a pattern element such as a variable, word, or number in the pattern
of <rule>

This occurs when a token such as => or <- is found within a pattern.


--Declaration is illegal at this point in <rule>.

This error occurs when a declaration is made after a pattern has been found
or if a declaration is made within a logical pattern operator such as and,
or, not.


--Missing a '(' after declare in <rule>

This error occurs when something other than an opening parenthesis follows a
declare token.


--Missing function declaration for function <function> in <rule>

This error occurs when the function called from either the LHS or RHS of a
rule is undefined, either because of a typo or because the user forgot to
define it in usrfuncs.


--Unable to find variable <name> on RHS of <rule>

This error occurs when a variable is reference on the RHS of a rule and is
neither bound on the LHS of the rule or in a bind statement preceding the
action in which the variable is mentioned.


--Unable to find variable <name> on LHS of <rule>

This error occurs when an unbound variable is referred to on the LHS of a
rule.  This can only occur within a test expression.


--Unable to find binder <name> on the RHS of rule

This error occurs when a retract statement references a fact binder that was
not de-fined within the LHS of the rule.

Example:

   (defrule foo ""
      ?f <- (a)
      =>
      (retract ?g))



--Missing deffacts name

This error occurs when the name is left off a deffacts block.


--Variable <name> is unbound in rule <rule>

This error occurs when a variable is referenced during the execution of a
rule, but has not yet been bound.  This can only happen to variables that are
defined in a bind statement. 

Example:

   (defrule foo ""
      (fact ?x)
           =>
       (if (> ?x 3) then (bind ?y 4))
           (assert (new-fact ?y)))

END-ENTRY

1MBEGIN-ENTRY-TEXT_PROCESSING

TEXT_PROCESSING

T.0 Text Processing
CLIPS provides a set of functions to build and access a hierarchical lookup
system for multiple external files.

Subtopics :

  ENTRY_FILE_FORMAT  PRINT-REGION
  FETCH              TOSS

END-ENTRY

2IBEGIN-ENTRY-ENTRY_FILE_FORMAT

TEXT_PROCESSING
  ENTRY_FILE_FORMAT

T.1 Entry File Format
Each file that is to be loaded into the internal lookup table must be described
in a particular way.  Each topic entry in each file must be in the format given
below : 

Format:

$$    <level-num> <entry-type> BEGIN-ENTRY- <topic-name>
          .                            
          .
      Topic information in form to be displayed when referenced.
          .
          .
$$    END-ENTRY

The delimeter strings must be the only things on their lines. Imbedded
white-space between the fields of the delimeters is allowed.

<level-num> is the level of the hierarchical tree to which the entry belongs.
The lower the number the closer to the root level the topic is, i.e., the
lowest level number indicates the root level.  Subtopics are indicated by
making the level number of the current topic larger than the previous entry
(which is to be the parent).  Thus, the tree must be entered in the file
sequentially, i.e., a topic with all its subtopics must be described before
going on to a topic at the same level. Entering a number less than the previous 
topic's will cause the tree to be searched upwards until a level number is
found which is less than the current one.  The current topic will then be
attached as a subtopic at that level. Thus, in this manner, multiple root trees
may be created. Level number and order of entry in a file can indicate the order
of precedence in which a list of subtopics which are all children of the same
topic will be searched.  Topics with the same level number will be searched in
the order that they appear in the file.  Topics with lower level numbers will be
searched first.

Example :

$$ 0MBEGIN-ENTRY-ROOT
$$ END-ENTRY
$$ 2IBEGIN-ENTRY-SUBTOPIC1
$$ END-ENTRY
$$ 1IBEGIN-ENTRY-SUBTOPIC2
$$ END-ENTRY

In the above example, SUBTOPIC1 and SUBTOPIC2 are both children of ROOT.
However, in searching the children of ROOT, SUBTOPIC2 would be found first.
                                                                              
<entry-type> must be a single CAPITAL letter code : M (for MENU) or I (for 
INFORMATION).  Only MENU entries may have subtopics.

<topic-name> can be any alphanumeric string of less than 80 characters. There
cannot be any white-space imbedded in the name.

Beginning a line with the delimeter `$$' forces the loader to treat the line
as pure text, even if one of the key delimeters is in it.  When the line is
printed, the dollar-signs are treated as blanks.

Example :

$$ 0MBEGIN-ENTRY-ROOT1
$$ END-ENTRY
$$ 1MBEGIN-ENTRY-1SUBTOPIC1
$$ END-ENTRY
$$ 2IBEGIN-ENTRY-11SUBTOPIC1
$$ END-ENTRY
$$ 1IBEGIN-ENTRY-1SUBTOPIC2
$$ END-ENTRY
$$ 0IBEGIN-ENTRY-ROOT2
$$ END-ENTRY
$$ -1MBEGIN-ENTRY-ROOT3
$$ END-ENTRY
$$ 0IBEGIN-ENTRY-3SUBTOPIC1
$$ END-ENTRY

Tree Diagram of Above Example :

   --> ROOT1 --> ROOT2 --> ROOT3
       /   \                 |
      /     \                |
     V       V               V
SUBTOPIC1 1SUBTOPIC2     3SUBTOPIC1
     |
     |
     V
11SUBTOPIC1

END-ENTRY

2IBEGIN-ENTRY-FETCH

TEXT_PROCESSING
  FETCH

T.2 fetch
fetch loads the named file (which must be in the appropriate format) into the
internal lookup table.

Syntax :

  (fetch <file-name>)

The function returns a non-zero integer if the fetch was successful.  If the 
file could not be loaded or already was loaded, the function returns zero.

END-ENTRY

2IBEGIN-ENTRY-PRINT-REGION

TEXT_PROCESSING
  PRINT-REGION

T.3 print-region
print-region looks up a specified entry in a particular file which has been
previously loaded into the lookup table and prints the contents of that entry
to the specified output.

Syntax :

  (print-region <logical-name> <lookup-file> [<topic-field(s)>])

<logical-name> is a name previously attached to an output device.  To send
the output to stdout, specify t for the logical name.

<lookup-file> is the name of the previously loaded file in which the entry
is to be found.

[<topic-fields(s)>] is the full path of the topic entry to be found. For 
example, to display on the screen the entry for ROOT SUBTOPIC from the file
foo.lis, you would type : (print-region t "foo.lis" ROOT SUBTOPIC).  Only
one entry can be accessed per print-region call.

Each element or field in the path is delimited by white-space, and the
function is not case sensitive.  In addition, the entire name of a field need
not be specified. Only enough characters to distinguish the field from other
choices at the same level of the tree are necessary (if there is a conflict, 
the function will pick the first one in the list).  For instance, 
(print-region t "foo.lis" roo sub) would be sufficient for the above example.

There are a few special fields that can be specified :
  ^    -  Branch up one level.
<nil>  -  Giving no topic field will branch up one level.

The level of the tree for a file remains constant between calls to print-region.
Thus, in order to access an entry at the root level after branching down
several levels in a previous call requires an equal amount of branch-ups.

END-ENTRY

2IBEGIN-ENTRY-TOSS

TEXT_PROCESSING
  TOSS

T.4 toss
toss unloads the named file from the internal lookup table and releases the
memory back to the system.  

Syntax :

  (toss <file-name>)

The function returns a non-zero integer if the toss was successful.  If the
file was not on the lookup table, it returns zero.

END-ENTRY

