loom2.1-install.text
With the introduction of lite instances, Loom now has the capability of asserting features on instances that are not classified.
CHANGE IN BEHAVIOR: Lite instances are now the default instance created by Loom. This default can be modified by using the "creation-policy" function documented in the section on the context mechanism. This change in default also affects the create function:
CREATE identifier concept &key :context :creation-policy :add-suffix-p [Function]Create a new instance of concept and assign it the identifier identifier. The type of instance created is determined by the creation policy of the indicated or current context, unless overridden explictly by the keyword creation-policy. If the policy :clos-instance is indicated but no appropriate CLOS class exists, a :classified-instance or :lite-instance will be created, and a warning issued. If add-suffix-p, then add a suffix if necessary to assure that the identifier is unique.
The keyword arguments :clos-instance-p and :suffix-p are now obsolete. They will continue to be recognized for a while to insure backward compatibility.
CREATION-POLICY &optional policy [Function]Set the creation policy of the current context to policy. Legal values are :classified-instance, :lite-instance, or :clos-instance. If policy is null, return the creation policy of the current context.
Compatibility Note: The default type of instance created is now :lite-instance rather than :classified-instance. If your application relies on having classified (i.e., Loom instances) and you use the create function you will need to add the :creation-policy keyword with the value :classified-instances. Alternately, one could evaluate the function creation-policy with the argument :classified-instance to set the default type of creation for a particular context.
Note: Loom instances have been renamed "classified instances."
(defconcept A) (defconcept B :is (not A)) (defconcept Status :is (:one-of 'OK 'Damaged 'Wrecked 'Sliced 'Diced 'Pulverized 'Obliterated)) (defrelation status) (defconcept Unit) (defconcept Hurting-Unit :is (:and Unit (not (:filled-by status 'OK))))
Assertions of the form
(tell (not (B i))) (tell (not (status u4 'sliced)))
are also permitted now.
The major change in behavior is that the extensions of concepts are now context-sensitive. This means that sibling KBs will no longer share all instances. The second major change is that functions which used to take a KB as a keyword argument now take contexts instead! A list of affected function appears further below.
User Note: Unless a context is created as a side effect of creating a
knowledge base, there is no way to save its contents to a file. That
is, the only function that saves information to a file is still the
save-kb
function. The context mechanism will be further developed in
Loom 3.0.
CC &optional contextName [Macro]Change context, or if contextName is null, return the current context.
CHANGE-CONTEXT contextOrName [Function]Replace the top of the context stack with the context contextOrName and reset the current context. Return the new current context.
CONTEXT-STACK [Function]Return the current context stack. The context stack is manipulated by pushing and popping contexts or by executing
change-context
.
CREATION-POLICY &optional policy [Function]Set the creation policy of the current context to policy. Legal values are :classified-instance, :lite-instance, or :clos-instance. If policy is null, return the creation policy of the current context.
CURRENT-CONTEXT [Function]Return the current context.
DEFCONTEXT contextName typeOfContext parentContexts [Macro] &key :creation-policy :monotonic-pCreate a new context called contextName of type typeOfContext that inherits the contexts parentContexts. Legal types are :theory, :workspace, :island, and :world. creation-policy indicates the meta-class for instances created in this context -- this establishes the inference policy for the context. Legal policies are
:classified-instance
, :lite-instance
, and
:clos-instance
. The default policy creates CLOS instances
for workspaces and LITE instances for theories.
DEFINE-CONTEXT name typeOfContext parentContexts [Function] &key :creation-policy :monotonic-pCreate a new context called contextName of type typeOfContext that inherits the contexts parentContexts. Legal types are :theory, :workspace, :island, and :world. creation-policy indicates the meta-class for instances created in context -- this establishes the inference policy for the context. Legal policies are
:classified-instance
, :lite-instance
, and
:clos-instance
. The default policy creates CLOS instances
for workspaces and LITE instances for theories.
DESTROY-CONTEXT contextOrName [Function]Destroy the context context and all contexts below it.
EXPORT-NAMES-IN-CONTEXT contextOrName [Function]Place names of all objects belonging to contextOrName on package export list(s).
FIND-CONTEXT contextOrName &key :error-p [Function]Return the context whose name matches contextOrName. If error-p, then generate an error if there is no such context. Note:
get-context
is slightly faster, but can't handle strings and
eliminates type checking.
GET-CONTEXT contextOrName [Function]Return the context whose name matches contextOrName. Assumes that a non-symbol is a legal context.
IN-CONTEXT contextName [Macro]Replace the top of the context stack with the context contextName and reset the current context. Unlike change-context, in-context evaluates at compile and load time.
It can only appear at top-level in a Lisp program.
PUSH-CONTEXT contextOrName [Function]Push the context contextOrName onto the context stack, and make it the current context. Return the new current context.
POP-CONTEXT [Function]Pop the current context from the context stack, and make the new top-most context on the stack the current context. Return the new current context.
LIST-CONTEXT &rest arguments [Macro]Return a list of objects in the specified partitions of the context named context. The :partitions keyword indicates what partitions are to be retrieved, while the optional parameter context indicates what context to use. Setting the keyword :sort-p to t causes the result to be sorted. Setting :sort-p to :sort-each-partition causes individual partitions to be sorted.
LIST-CONTEXTS [Function]Return a list of all contexts defined in Loom.
WITHIN-CONTEXT contextOrName &body body [Macro]Execute body with context temporarily set to contextOrName. This wrapper performs a
push-context
before executing body and a
pop-context
afterwards.
ADD-TYPE instanceOrId conceptOrName &key context no-error-p ADD-VALUE instanceOrId roleOrName fillerOrId &key context no-error-p ASK query &key context generators 3-valued-p COPY-INSTANCE instance &key identifier copy-into context add-suffix-p CREATE identifier concept &key context creation-policy CREATEM identifier concept &key context creation-policy FASK query &key context generators 3-valued-p FC conceptName &key context FI instanceSymbol &key context FIND-ALL term &key context FIND-CONCEPT conceptOrName &key no-warning-p ignore-package-p context FIND-INSTANCE instanceOrSymbol &key no-warning-p context ignore-package-p FIND-RELATION relationOrName &key no-warning-p ignore-package-p context FIND-THE term &key context FP productionName &key context FR relationName &key context FRETRIEVE outputVariables query &key context generators GET-CONCEPT conceptOrName &key context no-error-p GET-INSTANCE self &key context error-p GET-INVERSE-VALUES instanceOrId roleOrName &key context no-error-p GET-RELATION relationOrName &key context arity no-error-p GET-VALUE instanceOrId roleOrName &key context no-error-p GET-VALUES instanceOrId roleOrName &key context no-error-p LIST-MONITORS &key context LIST-PRODUCTIONS &key context REMOVE-TYPE instanceOrId conceptOrName &key context no-error-p REMOVE-VALUE instanceOrId roleOrName fillerOrId &key context no-error-p RETRIEVE outputVariables query &key context generators SET-VALUE instanceOrId roleOrName fillerOrId &key context no-error-p SET-VALUES instanceOrId roleOrName fillersOrIds &key context no-error-p
The following function used to take :destroy-kbs-p as a keyword argument. It no longer accepts that argument. Instead it takes :destroy-contexts-p.
INITIALIZE-NETWORK &key destroy-contexts-p
The following extensions have been made to the Loom language to support time:
(defrelation R) ; non-temporal (defrelation TR :characteristics :temporal) ; temporal (defconcept TC :characteristics :temporal) ; temporal (defconcept TC2 :is-primitive TC) ; temporal also
The temporal characteristic implies the :backward-chaining and :closed-world charateristics as well. At this time only concepts and binary relations are supported by the time manager. We will only consider supporting N-ary relations if user demand justifies the effort.
Temporal attributes can be used in the definition of concepts as well:
(defconcept Woman) (defrelation Husband :characteristics :temporal) (defconcept Married-Woman :is (:and Woman (:exactly 1 Husband)) :characteristics :temporal)
(n.B. Loom can infer that the concept Married-Woman must be temporal)
Most Loom reasoning works with these extended definitions. The exception is the generation of beginning and ending times of intervals for concepts that use value restrictions. This is discussed in more detail in the section on Queries.
Date conversion and parsing utilities for Loom do, however, use the format of CommonLisp universal time. This is the number of seconds since January 1, 1900. It is always a positive number.
For any assertion in Loom that holds over a time interval T, that assertion is also true over any sub-interval of T. In Allen's terminology that means that temporal concepts and relations are properties. In Shoham's terminology it means that they are liquid.
The value of a filler or the membership of an instance in a concept can be queried at particular points in time. The value returned is determined by evaluating the time using limit semantics. This semantics are designed so that we can give unambiguous and well founded answers at the endpoints of intervals.
For example, consider the statement (A Fred) holding from time 1 to 5. It is clear that (A Fred) holds at time 3. What answer is appropriate at time 1? The answer Loom will return is based on which of the query forms (detailed below) is used. (A Fred) holds in the limit as the time approaches 1 from the future end of the time line. (A Fred) does not hold in the limit as time approaches 1 from the past end of the time line. Each of these questions can be asked in Loom. In addition, if no direction is specified, (A Fred) will hold only if it holds in the limit from both directions. That is, (A Fred) does not hold at 1 or 5, but does at 2, 3 and 4.
"August 25, 1993" "11/11/75"
and times that can be parsed are
"10:30" "22:30" "10:30am" "10:30 pm" "Noon"
and, of course, combined date and time strings. Unspecified values will default to today for dates and to zero for times.
Localization Note: Only American style dates are parsed (sorry), but if the Europeans are interested, the date parsing mechanism is sufficiently flexible that other formats can be easily added. This is also true of the output function.
(:year 1993 :month 8 :day 25 :hour 10 :minute 30)
Times specified in this format will be converted to CommonLisp universal time with a granularity of seconds. As an extension to the KRSL standard, the keyword :second can also be used in Loom. Unspecified values will default to today for dates and to zero for times.
The Loom parser is able to parse any combination of these three forms on input. Output is (by default) in string format. For output in KRSL or integer format, see the section "Environment Control" below.
The syntax for making temporal assertions is:
(<TemporalOperator> <TimeSpec> <SimpleTemporalClause>*) <TemporalOperator> ::= :holds-after | :holds-before | :holds-at | :begins-at | :ends-at <TimeSpec> ::= <Integer> | <TimeString> | <KRSL-List> <SimpleTemporalClause> ::= (<Concept> <Instance>) | (<Relation> <Instance> <Filler>)
Examples:
(tell (:holds-after 10 (TC Fred) (TR Fred 5) (TR Fred 8))) (tell (:about Sue (:holds-before "1/1/86" TC (TR 6) (TR 9))))
Simple temporal assertions may not contain connectives such as :and or :or. Multiple clauses are permitted as syntactic sugar. The meaning of
(:holds-after 10 (TC Fred) (TR Fred 5) (TR Fred 8))
is the same as the combination:
(:and (:holds-after 10 (TC Fred)) (:holds-after 10 (TR Fred 5)) (:holds-after 10 (TR Fred 8)))
Note that this syntax is legal inside an :about clause, in which case concept and relation syntax changes analogously with regular Loom conventions.
:holds-after (:holds-before) This operator means that an assertion is true in the limit after (or before) the time specified. The assertion will persist forward (backward) in time. This form can result in a clip of another temporal assertion only in the case of single valued relations. In particular, NO statement is made about the value of the assertion before (after) the time point in question.
Aside from the clipping of single-valued roles, the only assertions that will terminate persistence are :begins-at and :ends-at. For example, the following assertions will have (TR Fred 3) over the entire time line!
(tell (:holds-after 0 (TR Fred 3)) (:holds-before 10 (TR Fred 3)))
This is because :holds-after says nothing about the value of TR before time 0. The persistence from the :holds-before at time 10 continues into the past and passes time 0.
:holds-at This temporal assertion is the equivalent of combining a :holds-after and a :holds-before at the same time. It is provided as a convenience.
:begins-at (:ends-at) These operators make a stronger statement than the :holds-after (:holds-before) operators. They assert that the statement is true in the limit after (before) the specified time point. They also assert that the statement is not true before (after) the specified time point. This negative assertion is used by Loom for persistence clipping and error detection. The negative assertion is not directly represented in the knowledge base but is derived from the closed world characteristics of Loom's temporal concepts and relations.
The following asserts that TR of Fred has the value 3 only from time 0 to time 10:
(tell (:begins-at 0 (TR Fred 3)) (:ends-at 10 (TR Fred 3)))
Note that because of the closed world nature of Loom's temporal representation, a single assertion of a :begins-at and a :holds-after create the same time line. The assertions differ in their interaction with the persistence of assertions at other times. Whereas a :begins-at will stop the backwards persistence of a fact, :holds-after will not.
Note that the following (one-way) implications are true:
:begins-at --> :holds-after :ends-at --> :holds-before :holds-at --> :holds-after :holds-at --> :holds-before
as well as the following equivalence:
:holds-before & :holds-after <--> :holds-at
(defrelation SR :characteristics (:single-valued :temporal)) (tell (:holds-after 0 (SR Fred 3)) (:holds-after 10 (SR Fred 4)))
The assertion of (SR Fred 4) at time 10 clips the forward persistence of (SR Fred 3). SR has the value of 3 from time 0 to time 10 and 4 thereafter.
(tell (:holds-after 0 (SR Fred 3)) (:holds-before 10 (SR Fred 4)))
We have 3 persisting forward from time 0 and 4 persisting backward from time 10. This is an incoherent state from which no well justified action can be taken. Loom stores both values of SR for the interval 0 to 10, but only one (determined at random) will be accessible via the query mechanism. The instance will belong to the concept Temporal-Incoherent during the interval 0 to 10. This is currently the only form of incoherence that we detect in the temporal representation.
The syntax for asking temporal queries is:
(<TemporalOperator> <TimeSpec> <LoomClause>) <TemporalOperator> ::= :holds-after | :holds-before | :holds-at | :begins-at | :ends-at <TimeSpec> ::= <Integer> | <TimeString> | <KRSL-List>
This syntax differs from that of assertions in two ways: (1) Only one clause is allowed in the body of the temporal operator. (2) The clause can be more complex. In particular, it can include conjunction and disjunction. (But see the semantic caveat about conjunctions below).
The meaning of the operators in queries is the same as in assertions:
:holds-after (:holds-before) The operator is satisfied if the LoomClause holds in the limit as time approaches from the future (past) end of the time line. The value of the LoomClause in the limit from the other direction is irrelvant.
:holds-at The clause must hold in the limit from both directions of the time line.
:begins-at (:ends-at) The LoomClause must hold in the limit as time approaches from the future (past) end of the time line. In addition, the LoomClause must not hold -- either by assertion with :begins-at (:ends-at) or through the closed world assumption from a :holds-after (:holds-before) -- in the limit as time approaches from the past (future) end of the time line.
Following the assertion of
(tell (:begins-at 0 (TC Fred)) (:end-at 10 (TC Fred)))
The following query returns the values shown in the table for different combinations of operator and time:
(ask (?op ?t (TC Fred))) +---------------+-----------------------------------------------+ | ?op | ?t= 0 5 10 | +---------------+-----------------------------------------------+ | :holds-at | nil T nil | | :holds-before | nil T T | | :holds-after | T T nil | | :begins-at | T nil nil | | :ends-at | nil nil T | +---------------+-----------------------------------------------+
To use one of these operators as a generator, the time argument is replaced by a variable:
(retrieve ?t (:begins-at ?t (TC Fred))) ==> (0) (ask (:exists ?t (:ends-at ?t (TC Fred)))) ==> T
Concepts that are defined using value restrictions (such as (:some R TC)) where TC is a temporal concept are allowed as temporal generators in queries. Because the search space for potential transition points involves looking not only at one instance, but also at the temporal transitions of the role fillers, these queries are slower.
(:begins-at T (:and A B C)) (:and (:begins-at T A) (:begins-at T B) (:begins-at T C)
The left form is satisfied by any T at which the conjunction becomes true. This can be satisfied by all three of A, B and C becoming true at time T. It can also be satisfied if B and C were already true and A became true at T, etc. The right form is satisfied only if all three of A, B and C become true at the same time (T). Ignorance of this distinction can lead to particularly subtle misunderstandings in the case where T is a variable.
*format-time-style* Legal values of the variable are :string, :krsl or nil. The default value is :string. If :string is chosen, then times will be formatted as a standard string such as "2/22/58 18:35:03". Particular details of the formatting are controlled by additional variables described below. If :krsl is chosen, then all printed times will be formatted as a list: (:YEAR 58 :MONTH 2 :DAY 22 :HOUR 18 :MINUTE 35 :SECOND 03). Note that this format extends the KRSL draft standard by adding :second as a field. If the value of this variable is NIL, then the time will appear as an integer. For the example time, this would be the CommonLisp universal time value 1834886103 (for the US West Coast).
All negative time values will be printed as integers regardless of the setting of this variable (i.e., formatting doesn't work for negative time values--dates before 1900). Years will be printed as two or four digit numbers in compatibly with the CommonLisp standard's convention.
The additional control variables are:
*format-time-smallest-unit* Legal values of this variable are :second, :minute, :hour, :day, :month, and :year. The default value is :second. This controls the smallest unit printed when :string or :krsl formatting is selected. It has no effect on the printing of integer values. If complete KRSL compliance is desired, the user should specify :minute as the smallest time unit displayed. This would change the previous examples to "2/22/58 18:35" and (:YEAR 58 :MONTH 2 :DAY 22 :HOUR 18 :MINUTE 35).
*format-time-include-date-p* Controls whether the date is included in the output. The default value is T. This controls operates only when :string or :krsl formatting is selected. It has no effect on the printing of integer values. The default (T) value results in printing as in the examples above. If the value is NIL, then only the time part will be printed: "18:35:03" and (:HOUR 18 :MINUTE 35 :SECOND 03).
*format-time-long-date-p* Controls whether the date is printed in a long form or in an abbreviated form. The default value is NIL, resulting in an abbreviated date. This variable only affects output in :string format. It has no effect on :krsl or integer values. If the value is nil, then dates will format as "2/22/58". If the value where T then the example's date would print as "February 22, 1958".