RELEASE NOTES FOR KM 2.0 ======================== SUMMARY OF RECENT CHANGES: - details are below under FULL RELEASE NOTES 2.2.2 - Bug fix for AURA - Added extra *on-error* option of "break", see below under 2.2.0 2.2.1 - Bug fix for AURA 2.2.0 - **NOTE** The parameters controlling behavior on errors have been rationalized to a single parameter. *abort-on-error-report*, *error-report-silent*, and *silently-abort-on-error-report* NO LONGER DO ANYTHING. Instead use the NEW variable *on-error* to define behavior on errors, with the following allowed values: VALUE KM'S BEHAVIOR ON ERRORS ===== ======================= abort Report error and do not continue, instead immediately return NIL. abort-silently Don't report error and do not continue, instead immediately return NIL. debug Report error and turn on debugger [DEFAULT] break Report error and break to Lisp continue Report error and continue. ignore Don't report error and do continue. e.g., (setq *on-error* 'continue) NOTE that with continuation (*on-error* = continue or ignore), KM will (as before when *error-report-silent* was t) assume a value of NIL for the computation where the error occurred. Again as before, this may cascade to cause other errors and may make the results of computation invalid, so use these two values with care. 2.1.39 - Change to the way prototypes are indexed: Previously: If you query an instance's slot, KM searches all prototypes whose PROTOTYPE-OF class(es) cover the instance, to see if those prototypes apply (and if so clones and unifies them in). New: If you query an instance's slot, KM searches all prototypes whose PROTOTYPE-SCOPE class(es) cover the instance, to see if those prototypes apply (and if so clones and unifies them in). 2.1.38 - API additions for use in the AURA system (no base KM changes) 2.1.37 - (setq *active-obj-stack* t) will make KM place objects more aggressively on the object stack, namely whenever they are encountered in an assertion to the KB (even if they are not new instances). - ( also-hasnt ( ())) This will DELETE on 's . If doesn't exist, KM will print a (non-interrupting) warning to the console. NOTE: KM won't undo inferences that depend on , i.e., there's no truth maintenance. Use with great care. 2.1.36 - User Manual Section 15.1 clarification: When do objects get placed on the object stack? Only when a *new* instance is created (has an assertion made about it): (X has (Y (Z))) - X will be added if X is a new instance. Z will be added if Z is a new instance. 2.1.32-35 - API additions for use in the AURA system (no base KM changes) 2.1.31 - (undo) will now unwind changes to the object stack. 2.1.30 - Bug fix (get-kb/put-kb failed to save the classification enabled/disabled state, now fixed). 2.1.28,29 - API additions/fixes for use in the AURA system (no base KM changes) 2.1.27 - Bug fix (save-kb/load-kb failed to save the classification enabled/disabled state, now fixed). - Tiny tweaks to allow KM to load under SBCL (Thanks to Tim Menzies) 2.1.24-26 - API additions for use in the AURA system (no base KM changes) 2.1.20-23 - Bug fixes. 2.1.19 - (km ) and (km-unique ) now return FOUR arguments: - result of evaluating - if an error occurred, a string describing it - if an error occurred, a structure describing it - if any warnings occurred, a list of strings (1 per warning) <- NEW - Below notes an incompleteness in KM, caused by (i) KM replacing a path with the result of evaluating a path and (ii) caching that the expression containing the path no longer needs to be re-inherited. If the KB changes so the path result is different, the path has been lost and thus won't be re-evaluated. KM> (every Person has (spouse ((a Spouse))) (likes ((a Thing with (owned-by ((the spouse of Self))))))) KM> (a Person) (_Person16) KM> (the owned-by of (the likes of _Person16)) (_Spouse18) ; NOTE: has evaluated and replaced the path ; (the spouse of _Person16) with the result _Spouse18 KM> (_Person16 has (spouse (*Sue))) ; now add new info to the KB [1] KM> (showme _Person16) (_Person16 has (instance-of (Person)) (likes (_Thing17)) (spouse (((_Spouse18) && (*Sue))))) KM> (the owned-by of (the likes of _Person16)) (_Spouse18) As the path (the spouse of Self) was earlier replaced by the result, _Spouse18, the last query does not re-evaluate the path and trigger unification of the &&. Note also that the last query (the likes of _Person16) won't re-inherit and re-evaluate the (a Thing...) expression to the likes slot of Person16 (which would allow the path (the spouse of _Person16) to be re-inherited to owned-by slot on _Thing17), as KM has already cached that _Thing17 was derived from that expression, blocking re-inheriting it. We can overcome this latter issue by clearing the entire cache after the KB changes (i.e., after [1]), at the expense of efficiency, via: (clear-evaluation-cache) Then we will get the desired result: KM> (the owned-by of (the likes of _Person16)) (*Sue) 2.1.18 - Bug fix 2.1.17 - Check that an instance/class doesn't have mutually inconsistent classes/superclasses (defined by Partitions) when asserting it into the KB, and report an error if a problem is found. If a partition violation occurs, and the tracer is switched off (by setting *abort-on-error-report* to t), then a structured error is returned (see comments under 2.0.62 below) of the form: (partition-violation ) where is either |instance-of| or |superclasses|. For example: USER: (setq *abort-on-error-report* t) USER: (km '#$(a Partition with (members (Male Female)))) USER: (km '#$(X has (instance-of (Male Female)))) Returns THREE values: val1-> nil val2-> "ERROR! Partition violation! X instance-of (Male Female): Some of these classes are mutually exclusive, _Partition1 violated" val3-> (partition-violation X instance-of (Male Female) (_Partition1)) NOTE (KM 2.1.20 and later): For a partition violation like this: USER: (km '#$(a Partition with (members (Male Female)))) USER: (km '#$(Male has (superclasses (Female)))) The structured val3 will look like this: (partition-violation Male superclasses (Male Female) (_Partition1)) Note that here the include Male, i.e., show how the partition was violated (rather than just list the asserted value Female). Thus in this case don't read as meaning the user asserted ( has ( )). 2.1.16 - ***EXPERIMENTAL AND MAY CHANGE*** Retaining expressions on instances: Normally after KM evaluates an expression on an instance's slot, the expression is replaced with the result, e.g., KM> (_Car1 has (parts ((a Engine)))) KM> (the parts of _Car1) (_Engine1) KM> (showme _Car1) (_Car1 has (parts (_Engine1))) However, we can make KM retain the original expression by wrapping it in a (retain-expr ) wrapper like this: KM> (_Car1 has (parts ((retain-expr (a Engine))))) KM> (the parts of _Car1) (_Engine1) KM> (showme _Car1) (_Car1 has (parts (_Engine1 (retain-expr (a Engine))))) KM> (the parts of _Car1) (_Engine1) This capability has been added for special reasons for the AURA system, and should NOT be used otherwise without good reason. NOTES AND LIMITATIONS: - Each time the slot is queried, the retain-expr will be re-evaluated UNLESS there is already a value on that slot that was created by an earlier evaluation of the retained expression. In this case, KM considers the retained expression "used", and won't reapply it. (The motivation for this is to avoid repeatedly creating new instances for instance-creating (retain-expr (a ...)) structures) - KM tells whether a value "was created by an earlier evaluation of the retained expression" by looking in KM's explanation database. Thus the explanation facility should not be switched off while using retain-expr (or, if it is switched off, then the retained expr will ALWAYS be re-evaluated each time the slot it is on is queried). - Unlike normal slot-value expressions, duplicate retain-exprs WILL be removed. Thus do not write: (_Person1 has (parts ((retain-expr (a Leg)) (retain-expr (a Leg)) as this will be simplified to (_Person1 has (parts ((retain-expr (a Leg))))) resulting in a one-legged person. Instead, you should write: (_Person1 has (parts ((retain-expr (:set (a Leg) (a Leg)))))) 2.1.15 - API modifications for use in the AURA system (save-prototype tweak). 2.1.14 - Minor bug fix (looping detector with constraints) 2.1.13 - Removed the distinction between Lisp calls (km ...) and (km0 ...) (Section 25 of the KM User Manual). It is no longer necessary to call (km0 ...) rather than (km ...) for recursive calls to KM -- now (km ...) can be universally called and KM itself will keep track of whether it is a recursive call or not. Users should phase out use of (km0 ...) and just use (km ...), although it is not an error to keep using km0. Similarly, km-unique0 can be phased out (just use km-unique instead). - (forall-seq nil ...) now returns nil (rather than generates an error) - (forall-bag nil ...) now returns nil (rather than generates an error) 2.1.12 - Fix typo (only affects unpacking KM into separate files, no functional change) 2.1.11 - Added a simple profiling mechanism: KM> (profile (the parts of (a Car))) CPU-TIME # CALLS 0.12 1 (the parts of (a Car)) 0.03 1 (a Engine) For the evaluation of this expression, the system reports the total CPU time that each subgoal was on the stack, and also the number of times it was on the stack (top 100 entries shown). This allows the user to see which the time-consuming items in the evaluation. (Note that CPU time is summed over all times an expression was on the stack, i.e., average CPU time per call is CPU time / # calls). CPU time is in seconds. KM> (profile-report) KM> (profile-report 200) Reprint the profile from the last (profile ) call, showing the top n (default 100) entries. 2.1.10 - Very special-case extension for unifying prototypes: inherit-with-overrides slots normally does NOT apply to unifying (clones of) prototypes. If there is an error, then the unification is aborted potentially leaving two partially unified structures. However, a very limited form of inherit-with-overrides for prototypes has been implemented as follows: IF values from two clones C1 and C2 are being unified AND the slot is declared as an inherit-with-overrides slot AND the values are NOT KB objects (frames) (for example: 1, (:pair 2 *kg), "hello") THEN the value(s) from C1 will override the value(s) from C2 i.e., the values from C2 are dropped When KM unifies clones of an instance's class's prototypes, it does so in a specific-to-general order. As a result, the above rule has the effect that values on the more specific class's prototype override the values on the more general class's prototype. 2.1.3-9 - Bug fixes and API modifications 2.1.2 - Missing from the original KM Documentation: (evaluate '): evaluates a quoted KM expression. KM> (evaluate '(1 + 2)) (3) 2.1.1 - *ONLY* for (the-class ...) expressions: Introduced the use of variables to express coreference. A variable starts with a "?". It can be used to denote a slot value OR can be used in the special form ( == (a ...)) to denote a slot value of a particular type. For example: (the-class Rectangle with (length (?x)) (width (?x))) (the-class Rectangle with (length ((?x == (a Number)))) (width (?x))) both denote the class of Rectangles with equal length and width (i.e., squares). A variable binds to a single slot value. IMPORTANT NOTES: - This use of variables is ONLY for the-class expressions, and can't be used elsewhere (e.g., in has-definition or has expression). - For slots with multiple values, if there is ambiguity about which value maches which variable KM will *NOT BACKTRACK* to retry different bindings if the first one fails (This is a limitation of the current implementation). As a result, try to make the bindings unambiguous by qualifying variables with type information, e.g., (the-class Car with (parts ((?x == (a Engine)) (?y == (a Chassis))))) rather than: (the-class Car with (parts (?x ?y))) 2.1.0 - inherit-with-overrides behavior has changed. For queries on an instance's inherit-with-overrides slots: OLD behavior (2.0.*): If there is already a value on the instance's slot, stop and return that. If not, find the "most specific inherited value", i.e., climb the class hierarchy until a value is found and return that. NEW behavior (2.1.*): Find any value on the instance's slot AND the most specific inherited value. If the inherited value can be unified with the local value, return the unification. Otherwise, just return the local value (i.e., the value on the instance's slot). The OLD behavior is still available using a renamed slot called simple-inherit-with-overrides. - NOW-HAS expressions (additional info, no functional change): If the same slot is used multiple times in the same (every ...) expr, later values will overwrite earlier values: KM> (every Car now-has (parts ((a Engine) (a Seat))) (parts ((a Wheel) (a Chassis)))) KM> (showme Car) (every Car has (parts ((a Wheel) (a Chassis)))) - New Lisp function (save-frame [:stream :slots-to-show :include-explanationsp ]) Writes the frame for to (default t). Default is to show all slots and no explanations; keyword arguments change this. e.g., (save-frame '#$Car :slots-to-show '#$(parts age)) 2.0.66 - bug fix for handling prototypes 2.0.65 - (trace-to-file-on "trace.txt") (trace-to-file-off) Redirects KM tracing output to a file, rather than the console. These can be issued both at the Lisp and KM prompts. 2.0.64 - (check-for-cycles) [Lisp function] Returns NIL if there are no cycles in the taxonomy, or the cycle as a list of successive superclasses, with the first and last elements being the same, if there are: USER: (km '#$(Car has (superclasses (Vehicle)))) USER: (km '#$(Vehicle has (superclasses (Car)))) USER: (check-for-cycles) (Car Vehicle Car) If there is more than one cycle, only the first encountered is returned. 2.0.63 - API modifications for use in the AURA system. 2.0.62 - - Extra keyword argument added to (put-kb [:unintern-symbols t]) (restore-kb [:unintern-symbols t]) If unintern-symbols = t, KM uninterns (removes from the symbol table) any symbols used in the current (to be reset) KB, but not used in the to-be-restored KB. NOTES: - only uninterns anonymous instance symbols (starting with "_") to avoid symbols in use elsewhere - use with caution if KM's anonymous instances are stored outside KM (e.g., in a global variable, e.g., if multiple KBs are stored in memory from (get-kb) calls), as these symbols will lose their package information if uninterned. - (km ) now returns THREE rather than TWO values: - result of evaluating - if an error occurred, a string describing it - if an error occurred, a structure describing it <-- NEW For this new third value, currently only constraint violation errors are returned as a structure with the following formats: 1. set constraint violations (error-type = '|set-constraint|) (set-constraint ) eg (set-constraint _Car1 parts (_Engine1 _Engine3) (exactly 1 Engine)) (set-constraint _Car1 parts (_Engine1 _Engine3) (at-most 1 Engine)) (note, there may be other slot-values, but these aren't returned) 2. val constraint violations (error-type = '|constraint|) (constraint ) eg (constraint _Car1 parts _Person2 (must-be-a Artifact)) (constraint _Car1 parts _Move3 (mustnt-be-a Event)) (constraint (_Car1 maker *Foo (possible-values *GM *Ford *Mercedes))) USAGE: From the Lisp prompt, ensure that the global variables controlling errors are set correctly (see Section 26.2, p85-86 in the User Manual): (let ((*abort-on-error-report* t) (*error-report-silent* nil)) (km )) 2.0.61 - API modifications for use in the AURA system. 2.0.60 - (clear-situations) - clears all situation-specific info from memory and takes KM out of situations mode. - (keeping-kb ... ) keeping-kb (a Lisp macro) evals all , but then undoes (using KM's undo mechanism) any side-effects in the KB. It returns the results of evaluating the last . e.g., USER: (reset-kb) USER: (keeping-kb (km '#$(a Car))) (_Car1) USER: (showme '#$_Car1) ;;; (Concept _Car1 is not declared anywhere in the KB) Thanks to Francis Leboutte for this utility. - Bug fix: (delete ) now works with (undo) 2.0.56-59 - API modifications for use in the AURA system. 2.0.55 - API modifications for use in the AURA system. A few small optimizations (thanks to Francis Leboutte). 2.0.54 - Minor extension to explanations with prototypes. 2.0.53 - Tiny bug fix to get-explanations with constraints. 2.0.52 - Bug fixes. Thanks to Fabien Dubail, Jason Chaw, and Sam (sds). 2.0.51 - Fix inefficiency in (get-all-concepts) introduced in 2.0.50 2.0.50 - Already in KM: (save-kb "tmp.km") saves the KB as a .km file (fastsave-kb "tmp.fkm") saves the KB as a faster-loading .fkm file KM 2.0.50 adds a third option: (faslsave-kb "tmp.fkm") does fastsave-kb AND Lisp-compiles it for even faster loading (.fasl extension in Allegro Lisp). (load-newest-kb ) loads the most recently written version of (.km, .fkm, or .fasl). does not need an extension (KM works out the most recent extension, and given extension is ignored). Thanks to Francis Leboutte for these additions. 2.0.49 - Modification of experimental functions, no KM change 2.0.48 - New optional keyword argument (... :reset-kb nil) added to save-kb and fastsave-kb. By default, save-kb and fastsave-kb include a (reset-kb) at the start of the saved KB. This keyword suppresses this. (save-kb "myfile.km" [:reset-kb nil]) (fastsave-kb "myfile.fkm" [:reset-kb nil]) 2.0.{45,46,47} - Modification of experimental functions, no KM change 2.0.44 - New experimental functions added for prototypes, to be documented later. No functional change to KM's normal behavior. 2.0.43 - Improved heuristics for unifying prototype clones together 2.0.42 - Obscure bug fix 2.0.41 - Extended and added the new KM commands for situation-based simulation: (do []) (do-and-next []) (try-do []) (try-do-and-next []) (do-concurrently []) (do-concurrently-and-next []) * (do ...) and (try-do ...) are as documented in the Situations manual, executing and testing executability of an action. * (do-concurrently ...) executes all from the same current situation, with a single resulting next situation. (Caveat: KM will not recognize or handle interference between ). * The subsequent situation following the action is if given, or a newly generated situation if not. * (...-and-next ...) causes KM to also change to the next situation; otherwise, KM remains in the current situation. 2.0.40 - Internal code changes to make KM run more smoothly on LispWorks. (Thanks to Raphael Van Dyck and Francis Leboutte) 2.0.39 - Added: (the seq2bag of ) - converts a single sequence to a bag (the bag2seq of ) - converts a single bag to a sequence - To remove an incompleteness, there is a minor change in the way backward chaining and classification are interleaved in KM: Classifications on newly created instances for a slot are now postponed until those values have actually been asserted on that slot (previously, classification kicked in at creation time rather than after assert time). 2.0.38 - Before: If you asserted a slot as an instance of a class, KM automatically asserted that the inverse slot was also a member of that class. Now: This has been removed, the assumption is not always valid. 2.0.37 - slight relaxation of caching in KM to overcome a reported bug 2.0.36 - bug fix (reset-kb) only removes KM info from property lists, rather than all 2.0.35 - Change prev-situation to be a multi-valued slot 2.0.34 - bug fix 2.0.33 - (setq *classify-slotless-instances* nil) will prevent KM trying to classify newly created instances which have no explicit slot-values. This is an optional efficiency improvement (default value is t). 2.0.32 - bug fix 2.0.31 - allow :incomplete keyword on slots, which informs KM more values may be arriving. This blocks definitions based on (exactly ..) or (at-most ...) constraints being satisfied, as :incomplete suggests new values may be added. This is an experimental addition for use in the AURA project. 2.0.30 - speed up reasoning with large numbers of defined concepts 2.0.29 - speed up reasoning with large numbers of defined concepts - add has-clones slot, the inverse of cloned-from 2.0.28 - bug fix (tiny change to unification algorithm) 2.0.27 - speed up reasoning with large numbers of defined concepts. NOTE: KM's implementation of Partition only assumes the partition's members are mutually exclusive, but not necessarily exhaustive. 2.0.26 - update to KM's explanation mechanism 2.0.25 - rename (install-all-subclasses) as (clean-taxonomy) - prevent KM adding in potentially redundant superclasses with has-definition expressions. 2.0.24 - bug fix 2.0.23 - For those few people working directly with the internal prototype representation...Allow comment tags in the prototype-scope expressions (Black-Cat has (superclasses (Cat))) (_Black-Cat1 has (instance-of (Black-Cat)) (prototype-of (Cat)) (prototype-scope ((the-class Cat with (color (*black)) [Comment1]))) (prototype-participants (_Black-Cat1)) (color (*black))) (comment [Comment1] (:seq "Therefore," Self "is a black cat.") (:seq "All cats which are black are black cats")) (*Suzie == (a Cat with (color (*black)))) (the color of *Suzie) ;;; Now: (justify (:triple *Suzie instance-of *)) ;;; Produces: All cats which are black are black cats Therefore, suzie is a black cat. NOTE: The justification is applied ONLY IF the prototype causes the class of the instance to change (specialize). Above, if *Suzie was already an instance-of Black-Cat, the justification would not be passed to *Suzie. 2.0.22 - (disable-classification) now also disables classification through the prototype mechanism - Code modification for load-exprs to avoid stack overflow in Lispworks (thanks to Francis Leboutte) 2.0.21 - Bug fix in simpleload-kb. Small extension to the explanation engine. 2.0.20 - Bug fix for (in-every-situation ...) construct 2.0.19 - Fix bug in error reporting accidentally introduced in 2.0.18 - KM now reports an error if there are cycles in the taxonomy 2.0.18 - bug fix for KM's explanation mechanism 2.0.17 - New parameter: *silently-abort-on-error-report* Like *abort-on-error-report*, except this also suppresses the error message printed in the console (Thanks to Francis Leboutte) - #t reader macro added (thanks to Francis Leboutte) Allows expressions within a #$ expression to be written just as at the normal Lisp prompt, rather than needing special package/case info. For example, as well as writing: (let ((car-instance (first (km '#$(the all-instances of Car))))) (km `#$(the parts of ,USER::CAR-INSTANCE))) you can now write equivalently: (let ((car-instance (first (km '#$(the all-instances of Car))))) (km `#$(the parts of ,#tcar-instance))) - modification to prototype application. Now KM will not attempt to unify in a prototype while unifying in a prototype (no recursive prototype application). - (showme-strings ) - Lisp function (not available at KM prompt). Like showme, except returns a string or list of strings describing , rather than just the list of s shown. 2.0.16 - Bug fix 2.0.15 - Bug fix for domains/ranges with multiple classes 2.0.14 - New built-in classes Pair, Triple, Sequence, and Bag added. Instances of these classes (and their superclasses) will now unify with :pair, :triple, :sequence, and :bag structures respectively. (Pair and Triple are subclasses of Sequence). Note that if such unifications occur, any slot-values on those instances will be dropped. - Redundant superclasses are now removed at assertion time, e.g.: KM> (Super2 has (superclasses (Super1))) KM> (Super3 has (superclasses (Super1 Super2))) ; Super1 redundant KM> (the superclasses of Super3) (Super2) ; note redundant Super1 removed 2.0.13 - Code changes to make KM loadable under Lispworks and SBCL (Thanks to Brian Mastenbrook and Francis Leboutte) - Remove hyphens printed by (get-justification [triple]) 2.0.12 - KM no longer needs to be preloaded before compiling! (Thanks to Brian Mastenbrook for explaining how to do this). - Explanation (comment tag) text is now formatted with make-phrase, rather than make-sentence, meaning that a period (".") is no longer automatically appended to explanation strings. - Small code tweaks so KM compiles under Lispworks (thanks to Francis Leboutte) 2.0.11 - no functional change (internal tweaks for CALO added) 2.0.6-10 - bug fixes and efficiency improvements 2.0.5 - Load-order independence for multifile KBs: (load-kb :load-patterns ) can now include a wildcard ?* denoting zero or more elements in a list. To ensure load order independence when loading multifile KBs, doing the following multipass load should work: (reset-kb) (load-kb :load-patterns '#$((?x has ?* (inverse ?y) ?*))) (load-kb :load-patterns '#$((?x has ?* (superclasses ?y) ?*))) (load-kb :load-patterns '#$((every &rest))) (load-kb ) where the 4 passes above correspond to loading: slot inverses, ontology, class axioms, and everything else. (Each pass should be applied to *all* files to be loaded, before moving onto the next pass). 2.0.4 - tweaks for compatibility with CLISP 2.0.3 - bug fixes 2.0.2 - bug fixes 2.0.1 - Prototypes: prototype-scope slot: Now allows multiple definitions for a prototype 2.0 - A new KM Manual has just been released and is up to date. SITUATIONS MANUAL ================= - IMPORTANT!!: The default fluent-status of slots is now *Fluent, *NOT* *Inertial-Fluent. Make sure the fluent-status of your slots are set correctly -- See the KM Situations Manual, Section 6.2, p23-24 for the rules to follow. - (do-script ). Obsolete. This is equivalent to (forall (the actions of ) (do-and-next It)) - (try-do ) (try-do-and-next ) Behaves like (do ), (do-and-next ) except it *tests* rather than *asserts* the preconditions of , and returns NIL if the preconditions are not satisfied. Set the global variable *interactive-preconditions* to t if you would like KM to then interactively ask the user whether to assume any unsatisfied preconditions are true. Section 10.3 - Changing instance-of relations between situations: - For efficiency, instance-of and instances are now, by default, *Non-Fluent slots (previously were *Inertial-Fluent). Their fluent status can be set to be *Inertial-Fluent using the special commands: (instance-of-is-fluent) This means that the example given here needs to be preceded by this command. (reset-kb) sets it back again. Peter Clark peter.e.clark@boeing.com ====================================================================== APPENDIX: NOTING KM ERRORS DURING REASONING ====================================================================== When an error occurs, as well as (by default) reporting it to the user and switching on the debugger, KM also stores a note of the error in a global variable. (km-errors) - returns the list of errors that have occurred (clear-km-errors) - clears this list This allows a program calling KM to see a structured form of the errors which occurred during reasoning, if any. (In addition to the text string value returned by (km ...) if an error occurs - see User Manual). NOTES: - Error recording is NOT part of KM's undo mechanism, i.e., an (undo) will not remove a recorded error from the list. - Errors are still recorded even if *error-report-silent* is set to t (= no textual error report and debugger activation)