Primitive and Defined Classes
This PowerLoom® example demonstrates some definition facilities for
primitive and non-primitive (or defined) concepts, and how such concepts
can be used in queries of various kinds.
Welcome to PowerLoom 3.0.1.beta
Copyright (C) USC Information Sciences Institute, 1997-2003.
PowerLoom is a registered trademark of the University of Southern California.
PowerLoom comes with ABSOLUTELY NO WARRANTY!
Type `(copyright)' for detailed copyright information.
Type `(help)' for a list of available commands.
Type `(demo)' for a list of example applications.
Type `bye', `exit', `halt', `quit', or `stop', to exit.
|= (demo 2)
Now reading from `PL:sources;logic;demos;classes.ste'.
Type `?' at the pause prompt for a list of available commands.
;;; -*- Mode: Lisp; Package: STELLA; Syntax: COMMON-LISP; Base: 10 -*-
;;; Version: classes.ste,v 1.17 2003/03/28 21:11:32 hans Exp
;;; Reasoning with primitive and defined concepts
;;; =============================================
;;; This file demonstrates some definition facilities for primitive
;;; and non-primitive or defined concepts, and how such concepts can
;;; be used in queries of various kinds.
;;; The best way to view this file is by calling `(demo)' and
;;; selecting it from the menu of example demos. This demo assumes
;;; familiarity with some basic PowerLoom concepts which are described
;;; in the introductory demo (#1 on the demo menu).
;; Standard demo preamble:
|= (in-package "STELLA")
------ pause ------c
|= (defmodule "PL-USER/CONCEPTS")
|MDL|/PL-KERNEL-KB/PL-USER/CONCEPTS
|= (in-module "CONCEPTS")
|= (clear-module "CONCEPTS")
|= (reset-features)
|l|(:EMIT-THINKING-DOTS :JUST-IN-TIME-INFERENCE)
|= (in-dialect KIF)
:KIF
;; We start by defining the concept `Person' with the already familiar
;; `happy' relation and `age' function:
|= (defconcept Person
:documentation "The class of human beings.")
|c|PERSON
|= (defrelation happy ((?p Person)))
|r|HAPPY
|= (deffunction age ((?p Person)) :-> (?age Integer))
|f|AGE
;; Next we define a primitive subconcept of `Person'. It is called
;; "primitive", since it is not fully defined in terms of other
;; concepts and relations, hence, there are some characteristics of
;; its members that are left implicit or primitive and are not further
;; explained in the knowledge base. The superconcepts of `Warfighter'
;; are listed following the concept name (with a syntax similar to
;; subclassing a CLOS class in Common Lisp):
|= (defconcept Warfighter (Person)
:documentation "People involved in military operations.")
|c|WARFIGHTER
;; The concept definition above is really only a shorthand that
;; expands into the following logically equivalent definition and
;; assertions (which we repeat here for exposition):
;; First, we define the concept term:
|= (defconcept Warfighter)
Redefining the `concept' named `WARFIGHTER'
|c|WARFIGHTER
;; Second, we assert the subconcept relationship via a `subset-of' assertion
;; (which PowerLoom interprets as a universally quantified rule):
|= (assert (subset-of Warfighter Person))
|P|(FORALL (?x1)
(<= (PERSON ?x1)
(WARFIGHTER ?x1)))
;; Finally, we attach a documentation string via a `documentation'
;; assertion. Note that the :documentation keyword used before is
;; not anything special built into the `defconcept' command, rather it
;; is a keyword axiom syntax where the name of the keyword is
;; interpreted to be the name of a binary relation, the first argument
;; is left implicit and taken to be the name of the defined entity and
;; the second argument is the supplied value, thus, it gets expanded
;; into the following assertion:
|= (assert (documentation Warfighter "People involved in military operations."))
|P|(DOCUMENTATION WARFIGHTER "People involved in military operations.")
;; This also demonstrates that concepts and relations can participate
;; as arguments to assertions just like any "ordinary" instance. A
;; query like the following can then be used to lookup the documentation
;; of a term:
|= (retrieve (documentation Warfighter ?doc))
There is 1 solution so far:
#1: ?DOC="People involved in military operations."
;; Now let's define armed services and some particular service instances:
|= (defconcept Armed-Service
:documentation "The class of armed services, for example, the US Navy.")
|c|ARMED-SERVICE
|= (assert (Armed-Service US-Army))
|P|(ARMED-SERVICE US-ARMY)
|= (assert (Armed-Service US-Navy))
|P|(ARMED-SERVICE US-NAVY)
|= (assert (Armed-Service US-Airforce))
|P|(ARMED-SERVICE US-AIRFORCE)
;; Next we define a `service' function that maps warfighters to the
;; branch of military service they operate in. Function inputs are
;; defined via optionally typed KIF variables such as the variable
;; `?p' below. Such variables can be listed simply by themselves or
;; as a list where the second element is interpreted as the variable
;; type. In the definition `?p's type is `Warfighter' which is taken
;; to be the domain of the function. There could be more than one
;; input argument, since PowerLoom allows n-ary functions and
;; relations. The function output is its last argument which is again
;; given as an optionally typed KIF variable separated via the :->
;; keyword. Below, the variable `?s' is typed as `Armed-Service'
;; which defines the range of the function. Similar to concepts and
;; relations, functions can have keyword axioms such as :documentation:
|= (deffunction service ((?p Warfighter)) :-> (?s Armed-Service)
:documentation "The armed service to which a warfighter belongs.")
|f|SERVICE
;; Again, the `deffunction' syntax is a shorthand that expands into
;; the following logically equivalent definition and assertions:
|= (deffunction service (?p) :-> ?s)
Redefining the `function' named `SERVICE'
|f|SERVICE
|= (assert (nth-domain service 0 Warfighter))
|P|(NTH-DOMAIN SERVICE 0 WARFIGHTER)
|= (assert (nth-domain service 1 Armed-Service))
|P|(NTH-DOMAIN SERVICE 1 ARMED-SERVICE)
|= (assert (documentation service
"The armed service to which a warfighter belongs."))
|P|(DOCUMENTATION SERVICE "The armed service to which a warfighter belongs.")
;; Functions can also be specified just like relations without the
;; special :-> keyword, for example, the following is yet another
;; equivalent definition:
|= (deffunction service ((?p Warfighter) (?s Armed-Service))
:documentation "The armed service to which a warfighter belongs.")
Redefining the `function' named `SERVICE'
|f|SERVICE
;; The function `friends' maps a person to its set of friends:
|= (deffunction friends ((?p Person)) :-> (?f SET)
:documentation "The set of friends ?f of some person ?p.")
|f|FRIENDS
;; Next we define a non-primitive (or defined) subconcept of `Person'
;; called `Civilian'. This is done by providing a bi-directional,
;; if-and-only-if implication between the concept and a defining
;; logical expression. In this case civilians are defined as people
;; who are not warfighters. This time the list of superconcepts is
;; preceded by a class variable `?p' which is needed so it can be
;; referenced in the defining expression. In primitive concept
;; definitions such as the ones above such variables can be ommitted.
;; Note, that since the definition is if-and-only-if, every person who
;; is not a warfighter is a civilian and vice versa.
|= (defconcept Civilian (?p Person)
:documentation "People who are not warfighters."
:<=> (and (Person ?p)
(not (Warfighter ?p))))
|c|CIVILIAN
;; The definition is a shorthand for the following logically equivalent
;; definition and assertions:
|= (defconcept Civilian)
Redefining the `concept' named `CIVILIAN'
|c|CIVILIAN
|= (assert (subset-of Civilian Person))
|P|(FORALL (?x1)
(<= (PERSON ?x1)
(CIVILIAN ?x1)))
|= (assert (documentation Civilian "People who are not warfighters."))
|P|(DOCUMENTATION CIVILIAN "People who are not warfighters.")
;; The defining bi-directional implication rule is translated by
;; PowerLoom into three equivalent regular implications:
|= (assert
(forall (?p)
(<=> (Civilian ?p)
(and (Person ?p)
(not (Warfighter ?p))))))
(|P|(FORALL (?p)
(<= (NOT (WARFIGHTER ?p))
(CIVILIAN ?p))) |P|(FORALL (?x1)
(<= (PERSON ?x1)
(CIVILIAN ?x1))) |P|(FORALL (?p)
(<= (CIVILIAN ?p)
(AND (PERSON ?p)
(NOT (WARFIGHTER ?p))))))
;; A note to Loom users: PowerLoom does not distinguish between
;; definitional and non-definitional parts of a concept or relation
;; definition. Any rule implying a concept or relation will be
;; considered by the inference engine and classifier, regardless of
;; whether it was part of the definition or asserted somewhere else
;; outside.
;; Let us define two more specialized classes of warfighters for
;; particular service branches:
|= (defconcept Army-Person (?p Warfighter)
:<=> (and (Warfighter ?p)
(= (service ?p) US-Army)))
|c|ARMY-PERSON
|= (defconcept Navy-Person (?p Warfighter)
:<=> (and (Warfighter ?p)
(= (service ?p) US-Navy)))
|c|NAVY-PERSON
;; Some instances of the concepts defined above:
|= (assert (Warfighter Buck))
|P|(WARFIGHTER BUCK)
|= (assert (= (service Buck) US-Army))
|P|(= (SERVICE BUCK) US-ARMY)
|= (assert (Person John))
|P|(PERSON JOHN)
;; We can use the built-in `member-of' relation to express set membership:
|= (assert (member-of Buck (friends John)))
|P|(MEMBER-OF BUCK (FRIENDS JOHN))
|= (assert (member-of John (friends Buck)))
|P|(MEMBER-OF JOHN (FRIENDS BUCK))
|= (assert (Person Judy))
|P|(PERSON JUDY)
;; Since so far we only know that Judy is a person, the following two
;; queries cannot derive any definitive answers:
|= (ask (Warfighter Judy))
UNKNOWN
|= (ask (Civilian Judy))
UNKNOWN
;; So, let us assert that Judy is a member of the US-Navy:
|= (assert (Warfighter Judy))
|P|(WARFIGHTER JUDY)
|= (assert (= (service Judy) US-Navy))
|P|(= (SERVICE JUDY) US-NAVY)
;; Now we can successfully determine that she is a Navy-Person:
|= (ask (Navy-Person Judy))
TRUE
;; The next query returns UNKNOWN, since (currently) PowerLoom does
;; not simultaneously try to answer a query and its negation with the
;; same effort (only "obvious" falsities are picked up):
|= (ask (Civilian Judy))
UNKNOWN
;; However, if we ask the negated question explicitly, we get the
;; expected result:
|= (ask (not (Civilian Judy)))
TRUE
;; The same works in the opposite direction:
|= (assert (Civilian Blimpy))
|P|(CIVILIAN BLIMPY)
|= (ask (Civilian Blimpy))
TRUE
;; Note, that this query does find the negated answer, since it has
;; already been derived by forward inference:
|= (ask (Warfighter Blimpy))
FALSE
|= (ask (not (Warfighter Blimpy)))
TRUE
;; Yet another warfighter:
|= (assert (Warfighter Fred))
|P|(WARFIGHTER FRED)
|= (assert (= (service Fred) US-Airforce))
|P|(= (SERVICE FRED) US-AIRFORCE)
;; Now, let us retrieve various sets of instances:
|= (retrieve all (Person ?p))
There are 5 solutions:
#1: ?P=JUDY
#2: ?P=JOHN
#3: ?P=BLIMPY
#4: ?P=FRED
#5: ?P=BUCK
|= (retrieve all (Warfighter ?w))
There are 3 solutions:
#1: ?W=FRED
#2: ?W=JUDY
#3: ?W=BUCK
|= (retrieve all (and (Person ?p) (not (Civilian ?p))))
There are 3 solutions:
#1: ?P=JUDY
#2: ?P=FRED
#3: ?P=BUCK
|= (retrieve all (and (Person ?p) (not (Warfighter ?p))))
There is 1 solution:
#1: ?P=BLIMPY
;; Retrieval of instances of defined classes:
|= (retrieve all (Civilian ?p))
There is 1 solution:
#1: ?P=BLIMPY
|= (retrieve all (Army-Person ?w))
There is 1 solution:
#1: ?W=BUCK
|= (retrieve all (Navy-Person ?w))
There is 1 solution:
#1: ?W=JUDY
;; Let us retrieve everybody who is either in the US-Navy or US-Airforce:
|= (retrieve all (and (Warfighter ?w)
(or (= (service ?w) US-Navy)
(= (service ?w) US-Airforce))))
There are 2 solutions:
#1: ?W=JUDY
#2: ?W=FRED
;; Alternatively, this can be done like this:
|= (retrieve all (and (Warfighter ?w)
(member-of (service ?w) (setof US-Navy US-Airforce))))
There are 2 solutions:
#1: ?W=JUDY
#2: ?W=FRED
;; Retrieve all people and their friends:
|= (retrieve all (and (Person ?p)
(Person ?f)
(member-of ?f (friends ?p))))
There are 2 solutions:
#1: ?P=BUCK, ?F=JOHN
#2: ?P=JOHN, ?F=BUCK
;; Retrieve all armed services with some members who have friends:
|= (retrieve all
(and (Armed-Service ?s)
(exists (?p ?w)
(and (Person ?p)
(Warfighter ?w)
(member-of ?p (friends ?w))
(= (service ?w) ?s)))))
There is 1 solution:
#1: ?S=US-ARMY
|=
Finished demo `PL:sources;logic;demos;classes.ste'.
|=
PowerLoom is a registered trademark of the University of Southern
California.
Last modified:
May 27, 2006