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'. |=