defconcept [Macro]


Purpose

The defconcept macro defines or redefines a concept.

Syntax

defconcept name &optional documentation
&key is is-primitive implies defaults partitions exhaustive-partitions in-partition
predicate function roles indices keys mixin-classes mixin-slots annotations
identifier kb characteristics

Arguments

The name argument is a symbol. If name is null, the concept is given a system-generated name.

The documentation argument is a string which attaches a comment to the concept being defined. This string can be retrieved by calling the Lisp documentation function with type as the doc-type argument.

The is and is-primitive arguments are concept-forming expressions (see Remarks below) that define the concept---that is, they specify a condition which is both necessary and sufficient for membership in the concept. These arguments are identical except that is-primitive introduces primitiveness into the definition. If neither argument is provided, then the concept is assumed to be a primitive specialization of the built-in concept Thing.

The implies and defaults arguments are concept-forming expressions (see Remarks below) that attach a rule to the concept---that is, they specify a condition which is implied by membership in the concept. The implies and defaults arguments introduce strict and default implications, respectively. Strict implications are always applied, while default implications are only applied when their consequents are consistent with the current state of the knowledge base.

The partitions and exhaustive-partitions arguments contain a symbol or list of symbols representing the partitions or exhaustive partitions owned by the concept being defined. Each partition P owned by concept C contains a set of subconcepts of C. If P is non-exhaustive, then an instance of C may not be an instance of more than one member of P. If P is exhaustive, then an instance of C must be an instance of exactly one member of P.

The in-partition argument states that the concept being defined is a member of the specified partition. The concept should directly specialize the owner of the partition.

The predicate argument consists of a one-variable lambda list followed by a body of Lisp expressions. With the variable bound to an object, the Lisp expressions can be evaluated to determine whether the object is a member of the concept being defined. This membership test supercedes the definition given in the is or is-primitive argument.

The function argument consists of an empty lambda list followed by a body of Lisp expressions that can be evaluated to generate the members of the concept being defined. This function supercedes the definition given in the is or is-primitive argument.

The roles argument is a relation name, or a list of relation names. Loom uses roles to generate slots on the CLOS class corresponding to the concept being defined. If any member of roles has not been defined, a multiple-valued binary relation is automatically created. (Typically, this relation will subsequently be redefined by the user.)

The indices argument is a list, each member of which is either a relation name or a list of relation names. For each entry in indices, Loom creates a hash index that accelerates retrieval based on the values of the roles specified by that entry. The hash index maps from a role filler to one or more instances. All roles in indices must be single-valued. The get-matching-instances function takes advatage of the indices, as does query for simple queries involving only types and role fillers. Currently, however, retrieve does not use the indices. The keys argument has the same form, and generally the same function, as the indices argument (see above). The principal difference is that the set of values of roles in a key must be unique for each instance in the corresponding concept. The specification of keys without corresponding indices does not provide accelerated access. Warnings are issued if (1) multiple instances are asserted to have the same value for a key, or (2) values are not supplied for all members of a key.

The class-name argument is the name to be given to the defined concept's shadowing CLOS class, if and when such a class is created. If this argument is not supplied, the new CLOS class will have the same name as the concept.

The existing-class-name argument is the name of an existing CLOS class which is to shadow the concept being defined, if such a class is needed for the creation of CLOS instances. Normally, the shadowing class is a newly-created CLOS class having the same name as the concept.

The mixin-classes argument is the name of a CLOS class, or a list of such names. A concept having mixin classes is automatically assigned the :clos-class characteristic. CLOS instances of such a concept inherit properties of the specified mixin classes as follows:

Users may provide their own mixins in addition to the above built-in classes.

The mixin-slots argument is a CLOS slot specifier, or a list of such specifiers. A concept having mixin slots is automatically assigned the :clos-class characteristic. The mixin-slots information is not used by Loom but instead is passed directly to the CLOS class definition facility. Thus, these slots don't necessarily correspond to any Loom relations. Loom assumes that the mixin-slots information has precedence over its own default behavior for constructing CLOS classes.

The annotations argument is a list of facts to be asserted about the concept being defined. Each element of the list is either a concept-name or an expression of the form (RelationName instance), where instance is either a constant or a symbol that identifies a Loom instance.

The identifier argument is the name under which the concept will be interned in the :instances partition of its knowledge base. This argument defaults to name.

The kb argument is a string or symbol that names the knowledge base in which the concept is to be interned. This defaults to the current knowledge base.

The characteristics argument is a keyword or list of keywords which specify various attributes of the concept. Concepts may have the following user-settable characteristics:

Concepts may also have the following Loom-assigned characteristics:

Value

The defined or redefined concept is returned.

Remarks

Negation is not yet supported in concept definitions.

There should only be one is or is-primitive keyword argument.

Concepts referenced in the is or is-primitive clause should not refer (directly or indirectly) to the concept being defined, since cycles are not permitted in definitions.

Currently, Loom automatically makes a concept backward-chaining if any of the following conditions hold:

Currently, Loom automatically makes a concept closed-world if any of the following conditions hold:

Currently, concepts with no primitiveness, and concepts defined with the :predicate option, are automatically marked :backward-chaining.

If a concept definition refers to a concept or relation that has not yet been defined, that concept or relation is immediately created by Loom.

In normal operation, a newly-defined concept is immediately classified, provided that all the concepts and relations it references have been classified.

  concept-expr ::= 
      ConceptName | 
      ( {:AND | :OR} concept-expr+ ) | 
      ( :ONE-OF {Number+ | InstanceId+} ) | 
      ( :THROUGH Number Number ) | 
      ( {:AT-LEAST | :AT-MOST | :EXACTLY} Integer relation-expr ) | 
      ( {:ALL | :SOME | :THE} relation-expr ConceptName ) | 
      ( {:FILLED-BY | :NOT-FILLED-BY} relation-expr  
                                      {InstanceId | Constant}+ ) | 
      ( {:SAME-AS | :SUBSET} relation-expr relation-expr ) | 
      ( {< | > | <= | >= | = | <>} relation-expr  
                                   {relation-expr | Number} ) | 
      ( :RELATES relation-expr relation-expr 
                               {relation-expr | Constant} ) | 
      ( :SATISFIES ( ?Var ) query-expr ) | 
      set-expr ;
The concept-forming expressions that appear in the is, is-primitive, implies, and defaults arguments above have the following syntax:

The concept-forming operators have the following semantics:

The auxiliary-definition keyword arguments having the following semantics:

Examples

(defconcept nil "Loom assigns name") ==> |C|THING_3 
(defconcept A) ==> |C|A
(defconcept B :is-primitive A)
(defconcept C :is (:and Adult Male Human))
(defconcept D :is (:or Dog Cat))
(defconcept E :is (:through 0 9))
(defconcept F :is (:one-of 7 11 13))
(defconcept G :is (:one-of Larry Moe Curly))
(defconcept H :is (:and A (:at-least 3 child) (:at-most 2 son)
(:exactly 1 pet)))
(defconcept I :is (:and A (:all child Happy) (:some son Teen-Ager)
(:the pet Dog)))
(defconcept J :is (:and A (:filled-by friend Bill Hillary)))
(defconcept K :is (:and A (:not-filled-by blood-type 'A-Pos)))
(defconcept L :is (:and A (:same-as wife best-friend)))
(defconcept M :is (:and A (:subset customer friend)))
(defconcept N :is (:and A (= length width) (> weight 100)))
(defconcept O :is (:and A (:relates divorced father mother)))
(defconcept P :is (:satisfies (?x) (:and (Dog ?x) (:fail (Purebred ?x)))))
(defconcept AA :implies (:and Expensive (:the chef French)))
(defconcept BB :defaults (:or (:filled-by class 'Senior) Grad-Student))
(defconcept CC :partitions (($PET$ (Dog Cat Bird Fish))))
(defconcept DD :exhaustive-partitions $PRIMATE$)
(defconcept EE :in-partition $PRIMATE$)
(defconcept FF :predicate ((n) (oddp n)))
(defconcept GG :function (() (loop for n from 0 to 9 collect n)))
(defconcept HH :roles (owner name breed age))
(defconcept II :indices (owner name breed) :keys (owner name))
(defconcept JJ :class-name ANIMAL)
(defconcept KK :existing-class-name INTEGER)
(defconcept LL :mixin-classes (INSTANCE-IN-KNOWLEDGE-BASE
INSTANCE-WITH-CONCEPTS))
(defconcept MM :annotations (Noun (plural "-es")))
(defconcept NN :identifier Age-as-Concept :kb user-kb)
(defconcept OO :characteristics (:closed-world clos-class))

See Also

Last modified: Dec 28 1995