3. Annotated Example
The section presents a small example of a PowerLoom knowledge
base. It introduces the fundamental PowerLoom modelling
concepts and illustrates the syntax of basic PowerLoom
declarations, assertions, and commands. This section can be
read stand-alone, but readers who intend to use PowerLoom to
create their own models are encouraged to load the demo file
???, and run the examples “live”.
The conceptual terms introduced in this section include modules,
concepts, relations, functions, instances, propositions, assertions,
queries, retraction, positive and negative facts, clipping, rules,
and contexts.
3.1 Using Modules
We begin by creating a PowerLoom “module”, which is a logical
container that holds the term definitions, rules, facts, etc.
that make up all or a portion of a domain model. We will call
our module business
. The defmodule
command defines a new
module. The :includes
option within the defmodule
tells
PowerLoom that the business
module inherits all definitions
and assertions present in the PL-USER
module, or in ancestor
modules inherited by the PL-USER
module. In particular, by
inheriting PL-USER
, we indirectly inherit the PL-KERNEL
module that contains all of the built-in concepts and relations.
The in-module
command tells the PowerLoom system
to make BUSINESS
the current module. Until the current module
is changed again, all new introductions of terms and facts will
be placed in the business
module.
| (defmodule "BUSINESS"
:includes ("PL-USER"))
(in-module "BUSINESS")
|
The basic building blocks of a model are its concepts, relations, and
instances.(3) A concept defines
classes/categories of entities that populate the domain model. A
relation defines attributes and relationships that allow the
declaration of facts about an entity. Instances are members of
concepts. They appear as arguments to propositional assertions.
3.2 Concepts
Concepts are defined using the defconcept
command. Here
we define the concepts company
and corporation
:
| (defconcept company)
(defconcept corporation (?c company))
|
The first definition tells the system that company
is a concept
(in the business
module). The second definition defines a
concept corporation
. The type declaration (?c company)
indicates that corporation
is a subconcept of company
, i.e.,
all instances of corporation
are also instances of company
.
Let us now create a couple of companies:
| (assert (company ACME-cleaners))
(assert (corporation megasoft))
|
These two assertions create two new entities denoted by the
terms ACME-cleaners
and megasoft
. Both of these entities
are members of the concept company
. megasoft
is also a member
of the concept corporation
. We can test this by executing some
PowerLoom queries:
| (retrieve all ?x (company ?x))
⇒
There are 2 solutions:
#1: ?X=ACME-CLEANERS
#2: ?X=MEGASOFT
(retrieve all ?x (corporation ?x))
⇒
There is 1 solution:
#1: ?X=MEGASOFT
|
3.3 Relations
So far, our two companies aren’t very interesting. In order to say more
about them, we can define some relations and functions using the
declarations defrelation
and deffunction
:
| (defrelation company-name ((?c company) (?name STRING)))
|
This declaration defines a binary relation company-name
.
The first value in a company-name
tuple must be an instance
of type company
, while the second value must be a string.
We can now give our companies names, using the command assert
:
| (assert (company-name ACME-cleaners "ACME Cleaners, LTD"))
(assert (company-name megasoft "MegaSoft, Inc."))
|
We can retrieve pairs of companies and their names with the following
query (note that we omitted the optional retrieval variables in which
case they are determined by collecting the free variables in the query
expression):
| (retrieve all (company-name ?x ?y))
⇒
There are 2 solutions:
#1: ?X=MEGASOFT, ?Y="MegaSoft, Inc."
#2: ?X=ACME-CLEANERS, ?Y="ACME Cleaners, LTD"
|
Using retrieval variables is useful if we want to order the result
columns in a certain way, for example:
| (retrieve all (?y ?x) (company-name ?x ?y))
⇒
There are 2 solutions:
#1: ?Y="MegaSoft, Inc.", ?X=MEGASOFT
#2: ?Y="ACME Cleaners, LTD", ?X=ACME-CLEANERS
|
3.4 Relation Hierarchies
PowerLoom permits the specification of hierarchies both for concepts and
relations. Previously , we defined a small concept hierarchy with
company
on top and corporation
below it. We now define a
subrelation of the relation company-name
called
fictitious-business-name
:
| (defrelation fictitious-business-name ((?c company) (?name STRING))
:=> (company-name ?c ?name))
|
PowerLoom defines a subconcept/subrelation relationship between
a pair of concepts or a pair of relations by asserting an “implication”
relation between them.
The above implication expands into the assertion
“for all values of ?c and ?name, if the fictitious-business-name
relation holds for ?c and?name, then the company-name
relation
also holds for ?c and ?name”. This is equivalent to the assertion
| (forall (?c ?name) (=> (fictitious-business-name ?c ?name)
(company-name ?c ?name)))
|
Since implication relationships occur very
commonly, PowerLoom provides several syntactic shortcuts for defining
them. We have seen one such shortcut earlier; our
definition of corporation
included the clause “(c ?company)
”,
which specified that corporation
is a subconcept of company
.
In our definition of fictitious-business-name
, the keyword
:=>
introduces a similar shortcut, which tells us that
fictitious-business-name
is a subrelation of company-name
.
Let us assert a fictious business name for MegaSoft:
| (assert (fictitious-business-name megasoft "MegaSoft"))
|
If we query for the company names of MegaSoft, we get two names,
one of them asserted directly, and one of them infered by the
subrelation rule:
| (retrieve all (company-name megasoft ?x))
⇒
There are 2 solutions:
#1: ?X="MegaSoft, Inc."
#2: ?X="MegaSoft"
|
3.5 Functions
This illustrates another point: A PowerLoom relation is by default
“multi-valued”, which in the case of a binary relation means that a
single first value can be mapped by the relation to more than one second
value. In the present case, our model permits a company
entity to
have more than one company-name
. If a (binary) relation always maps
its first argument to exactly one value (i.e., if it it “single-valued”)
we can specify it as a function
instead of a relation
. For
example, we can use a function to indicate the number of employees for a
company:
| (deffunction number-of-employees ((?c company)) :-> (?n INTEGER))
|
When defining a function, all arguments but the last appear just as they
do for a relation. The last argument (and its type) appears by itself
following the keyword :->
. Defining a single-valued relation as a
function allows us to refer to it using a functional syntax within a
logical sentence, as in the following:
| (assert (= (number-of-employees ACME-cleaners) 8))
(assert (= (number-of-employees megasoft) 10000))
|
The functional syntax often results in shorter expressions than
equivalents that use relational syntax. For example to retrieve all
companies with fewer than 50 employees, we can simply write:
| (retrieve all (and (company ?x) (< (number-of-employees ?x) 50)))
⇒
There is 1 solution:
#1: ?X=ACME-CLEANERS
|
Using the syntax for relations, the same query would require the
introduction of an existential quantifier, as in:
| (retrieve all (and (company ?x)
(exists ?n
(and (number-of-employees ?x ?n)
(< ?n 50)))))
⇒
There is 1 solution:
#1: ?X=ACME-CLEANERS
|
To repeat ourselves slightly, Powerloom allows users the choice of using
either relational or functional syntax when using a function in predicate
position. For example, if f
is a function, then the expressions
(f ?x ?y)
and (= (f ?x) ?y)
are equivalent.
3.6 Defined Concepts
If we find ourselves writing the same query (or subexpression) repeatedly,
we may wish to define a name for the concept embodying that expression.
For example, below we define the term small-company
to represent
the class of all companies with fewer than 50 employees:
| (defconcept small-company ((?c company))
:<=> (and (Company ?c)
(< (number-of-employees ?c) 50)))
|
Notice that we have used a new keyword, :<=>
. This keyword defines a
bidirectional implication called “if-and-only-if”. Formally it is
equivalent to the following pair of assertions:
| (assert (forall ?c (=> (and (Company ?c)
(< (number-of-employees ?c) 50))
(small-company ?c))))
(assert (forall ?c (=> (small-company ?c)
(and (Company ?c)
(< (number-of-employees ?c) 50)))))
|
In other words, the :<=>
keyword is a shortcut for an assertion that
uses the <=>
relation, which itself is a shortcut representing the
conjunction of two single arrow implications. For example, (<=> P Q)
is equivalent to (and (<= P Q) (=> P Q))
, where the <=
relation is defined to be the inverse of the relation =>
.
Its not necessary that we exactly specify the number of employees in a
company. Below, all we know about ZZ Productions is that they have
fewer than 20 employees:
| (assert (and (company zz-productions)
(< (number-of-employees zz-productions) 20)))
|
These facts are sufficient to classify ZZ Productions as a small
business:
| (retrieve all (small-company ?x))
⇒
There are 2 solutions:
#1: ?X=ZZ-PRODUCTIONS
#2: ?X=ACME-CLEANERS
|
3.7 Negation and Open and Closed World Semantics
PowerLoom implements a three-valued logic—the truth value of each
proposition entered into a PowerLoom knowledge base is recorded as
being either true, false, or unknown.(4) Many other
systems (e.g., relational DBMSs) implement a two-valued logic, wherein
if a fact is not asserted to be true, it is assumed to be false. The
PowerLoom command ask
returns one of three (five) values:
true
if it can prove the truth of a proposition, false
if it can easily prove the falsity of a
proposition(5) and otherwise
it returns unknown
. (The values default-true
and
default-false
are also possible if defaults are used).
Below, PowerLoom knows nothing about a newly-introduced concept
s-corporation
, so ask
returns unknown
to both a
positive query and its negation:
| (defconcept s-corporation (?c corporation))
(ask (s-corporation zz-productions))
⇒
UNKNOWN
(ask (not (s-corporation zz-productions)))
⇒
UNKNOWN
|
If we assert that ZZ Productions is not an S-corporation, then
PowerLoom knows that the proposition in question is false:
| (assert (not (s-corporation zz-productions)))
(ask (s-corporation zz-productions))
⇒
FALSE
(ask (not (s-corporation zz-productions)))
⇒
TRUE
|
After asserting that ZZ Productions is not an S-corporation,
a repeat of the query asking if it is one will now return false
,
because the explicit assertion of the negation allows a quick disproof of
the positive query.
Note: PowerLoom uses all its effort to prove that the
proposition in question is true, and only uses some effort to prove that
it is false. Therefore, only falsities that are discovered "on the way"
or with shallow inference strategies will be found (which was the case
above). If you want to check whether a proposition is false with
maximum effort, simply ask the negated proposition by wrapping an
explicit not
arount it. The reason for this asymmetry is that
checking for truth and falsity really amounts to asking two separate and
possibly expensive queries, and the user or programmer should decide
whether the effort should be expended to ask both queries instead of
just one.
PowerLoom can sometimes infer a negative fact without
the necessity of a direct assertion. For example:
| (ask (= (number-of-employees ACME-cleaners) 8))
⇒
TRUE
(ask (= (number-of-employees ACME-cleaners) 10))
⇒
FALSE
(ask (not (= (number-of-employees ACME-cleaners) 10)))
⇒
TRUE
|
PowerLoom can infer the second and third answers because it knows that
the function number-of-employees
can return only one value, and
if that value is the number eight, it cannot also be something else (in
this case, ten).
Many systems, in particular, database systems and Prolog, make the
assumptions that if a proposition cannot be proved true, then it must be
false. This is called the “closed world assumption”. By default,
PowerLoom makes an open-world assumption, but for specific relations it can
be instructed to assume a closed world if a user wants closed world
semantics. For example, suppose we introduce a relation works-for
,
and we assume that all works-for
facts have been entered in our
knowledge base:
| (defrelation works-for (?p (?c Company)))
(assert (works-for shirly ACME-cleaners))
(assert (works-for jerome zz-productions))
|
If we ask PowerLoom whether Jerome does NOT work for MegaSoft, it will
return unknown
. But if we assert that the relation
works-for
is closed
, then PowerLoom will assume that
Jerome only works for ZZ Productions:
| (ask (not (works-for jerome megasoft)))
⇒
UNKNOWN
(assert (closed works-for))
(ask (not (works-for jerome megasoft)))
⇒
TRUE
|
The reasoning employed to achieve the above result (that Jerome does not
work for MegaSoft) is called “negation as failure”, which means that
if a proof of a proposition fails, then one may assume that the
proposition is false. We can achieve a negation-as-failure result a
second way (i.e., other than by using a closed world assumption) by
employing the query operator fail
. Here we retract the closure
assumption for works-for
and achieve the desired result using
fail
:
| (retract (closed works-for))
(ask (not (works-for jerome megasoft)))
⇒
UNKNOWN
(ask (fail (works-for jerome megasoft)))
⇒
TRUE
|
When you see the operator “not” in an SQL query or a Prolog program,
it really stands for “fail”.
3.8 Retraction
Below, we introduce a few new terms for defining geographic information.
We define a relation called contains
to assert that one geographic
location (the second argument to contains
) is located within another:
| (defconcept geographic-location)
(defconcept country (?l geographic-location))
(defconcept state (?l geographic-location))
(defconcept city (?l geographic-location))
(defrelation contains ((?l1 geographic-location)
(?l2 geographic-location)))
|
Now, we can assert some facts about U.S. geography (including one
deliberate mistake):
| (assert (and
(country united-states)
(geographic-location eastern-us)
(contains united-states eastern-us)
(state georgia) (contains eastern-us georgia)
(city atlanta) (contains georgia atlanta)
(geographic-location southern-us)
(contains united-states southern-us)
(state texas) (contains eastern-us texas)
(city dallas) (contains texas dallas)
(city austin) (contains texas austin)))
|
We would like to repair the incorrect assertion (contains eastern-us texas)
.
The PowerLoom command retract
allows us to erase assertions that
should not be true:
| (ask (contains eastern-us texas))
⇒
TRUE
(retract (contains eastern-us texas))
(assert (contains southern-us texas))
(ask (contains eastern-us texas))
⇒
UNKNOWN
|
Retraction should not be confused with assertion of negative propositions.
For example, asserting that Texas is not a state would not retract
the assertion that it is (a state). Instead, an evident logical contradiction
is detected as a “clash”, and the clashing proposition is disallowed:
| (assert (not (state texas)))
⇒
Derived both TRUE and FALSE for the proposition `|P|(STATE TEXAS)'.
Clash occurred in module ``|MDL|/PL-KERNEL-KB/business'.
(ask (not (state texas)))
⇒
UNKNOWN
|
3.9 Clipping of Values
Programmers are accustomed to changing the values of attributes for
program objects just by overwriting previous values. PowerLoom implements a
similar semantics for the special case of functions and single-valued
relations. When a second value is asserted for one of these relations
the previous value is automatically retracted. We call this clipping.
To illustrate this behavior for both kinds of relations (a function is
considered a kind of relation), we will define a mapping from a company to
a city that contains its headquarters in two different ways:
| (deffunction headquarters ((?c company)) :-> (?city city))
(defrelation headquartered-in ((?c company) (?city city))
:axioms (single-valued headquartered-in))
|
The clause ":axioms (single-valued headquartered-in)
" tells
PowerLoom that the headquartered-in
relation is single-valued,
i.e., that it can map a company to at most one city. This makes its
behavior similar to that of the function headquarters
. Here is
an example of clipping for the function headquarters
:
| (assert (= (headquarters zz-productions) atlanta))
(retrieve all (= ?x (headquarters zz-productions)))
⇒
There is 1 solution:
#1: ?X=ATLANTA
(assert (= (headquarters zz-productions) dallas))
(retrieve all (= ?x (headquarters zz-productions)))
⇒
There is 1 solution:
#1: ?X=DALLAS
|
Here is the same kind of clipping using a single-valued relation:
| (assert (headquartered-in megasoft atlanta))
(retrieve all (headquartered-in megasoft ?x))
⇒
There is 1 solution:
#1: ?X=ATLANTA
(assert (headquartered-in megasoft dallas))
(retrieve all (headquartered-in megasoft ?x))
⇒
There is 1 solution:
#1: ?X=DALLAS
|
3.10 Rule-based Inference
Suppose that we want to retrieve all geographic locations that are
contained in the Southern US, based on the set of assertions about
geography that we entered in earlier. The following query returns only
one of such location:
| (retrieve all (contains southern-us ?x))
⇒
There is 1 solution:
#1: ?X=TEXAS
|
We would like the cities Austin and Dallas to be retrieved as well.
To do this, we can assert a rule
that states that contains
is a transitive relation:
| (defrule transitive-contains
(=> (and (contains ?l1 ?l2)
(contains ?l2 ?l3))
(contains ?l1 ?l3)))
|
The defrule
declaration does two things—it asserts a
proposition, and it associates a name with that proposition (in the
above case, the name is transitive-contains
). This name is used by
the system in displaying traces of its inferencing. It also makes
redefinition of the proposition easier. If we wish to retract an unnamed
proposition, it is necessary to explicitly retract that proposition
using a syntax identical to the assertion(6) If on the
other hand, a proposition has a name, then a new defrule
declaration that uses the same name will automatically retract any
existing proposition having the same name.
Our transitive closure rule failed to include any logical quantifiers
for the variables ?l1
, ?l2
, and ?l3
. When PowerLoom
parses a top-level proposition, it automatically supplies universal
quantifiers for any unquantified variables. So, the above rule is
equivalent to the rule:
| (defrule transitive-contains
(forall (?l1 ?l2 ?l3)
(=> (and (contains ?l1 ?l2)
(contains ?l2 ?l3))
(contains ?l1 ?l3))))
|
Note: Instead of defining a transitive-contains
rule,
we could have achieved the same effect by asserting that the contains
relation is transitive, e.g., by stating (assert (transitive contains))
.
Now that we have told the system that our contains
relation is
transitive, let us rerun our query:
| (retrieve all (contains southern-us ?x))
⇒
There are 3 solutions:
#1: ?X=TEXAS
#2: ?X=AUSTIN
#3: ?X=DALLAS
|
3.11 Explanation
PowerLoom provides a command called why
that you can use to
get an explanation of the logic behind one of its answers. The
why
command explains the last query entered into the system,
i.e., it should invoked after one has submitted a retrieve
or
an ask
command. Before asking a why
command, you must
enable the justifications feature:
| (set-feature justifications)
|
Queries execute a bit more slowly with jusifications enabled, which is why it is
disabled by default. Having enabled justifications, we must (re)run a query.
Here is how we can ask why Dallas is contained in the Southern US:
| (ask (contains southern-us dallas))
⇒
TRUE
(why)
⇒
1 (CONTAINS SOUTHERN-US DALLAS)
follows by Modus Ponens
and substitution {?l3/DALLAS, ?l2/TEXAS, ?l1/SOUTHERN-US}
since 1.1 ! (forall (?l1 ?l3)
(<= (CONTAINS ?l1 ?l3)
(exists (?l2)
(and (CONTAINS ?l1 ?l2)
(CONTAINS ?l2 ?l3)))))
and 1.2 ! (CONTAINS SOUTHERN-US TEXAS)
and 1.3 ! (CONTAINS TEXAS DALLAS)
|
The above explanation tells us that a rule (our transitivity rule)
was invoked during the proof, and that two ground assertions
(CONTAINS SOUTHERN-US TEXAS)
and (CONTAINS TEXAS DALLAS)
were accessed to supply preconditions for the rule. These combined
assertions lead to the conclusion (CONTAINS SOUTHERN-US DALLAS)
.
Within an explanation, directly asserted propositions are indicated with
the prefix ‘!’.
We can also ask why
after a retrieve
query. However, if the
query has multiple solutions, each one has a separate explanation. In order
to ask why
, we need to ask for one solution at a time. This can be
done by omitting the word all
from the retrieve
query, and
subsequently calling (retrieve)
to obtain results one-at-a-time.
(7)
| (retrieve (contains southern-us ?x))
⇒
#1: ?X=DALLAS
(retrieve)
⇒
There are 2 solutions so far:
#1: ?X=DALLAS
#2: ?X=TEXAS
(retrieve)
⇒
There are 3 solutions so far:
#1: ?X=DALLAS
#2: ?X=TEXAS
#3: ?X=AUSTIN
(why)
⇒
1 (CONTAINS SOUTHERN-US AUSTIN)
follows by Modus Ponens
with substitution {?l1/SOUTHERN-US, ?l3/AUSTIN, ?l2/TEXAS}
since 1.1 ! (FORALL (?l1 ?l3)
(<= (CONTAINS ?l1 ?l3)
(EXISTS (?l2)
(AND (CONTAINS ?l1 ?l2)
(CONTAINS ?l2 ?l3)))))
and 1.2 ! (CONTAINS SOUTHERN-US TEXAS)
and 1.3 ! (CONTAINS TEXAS AUSTIN)
|
The following query combines a variety of relations that have been
entered into the business modules. It retrieves names of companies
whose headquarters are in the southern US. Note that query variables
that do not appear in the output (i.e., variables not listed after the
all
| (retrieve ?name (exists (?city ?company)
(and (contains southern-us ?city)
(headquartered-in ?company ?city)
(company-name ?company ?name))))
⇒
There is 1 solution so far:
#1: ?NAME="MegaSoft, Inc."
(why)
⇒
1 (and (COMPANY-NAME MEGASOFT MegaSoft, Inc.)
(HEADQUARTERED-IN MEGASOFT DALLAS)
(CONTAINS SOUTHERN-US DALLAS))
follows by And-Introduction
since 1.1 ! (COMPANY-NAME MEGASOFT MegaSoft, Inc.)
and 1.2 ! (HEADQUARTERED-IN MEGASOFT DALLAS)
and 1.3 (CONTAINS SOUTHERN-US DALLAS)
1.3 (CONTAINS SOUTHERN-US DALLAS)
follows by Modus Ponens
and substitution {?l3/DALLAS, ?l2/TEXAS, ?l1/SOUTHERN-US}
since 1.3.1 ! (forall (?l1 ?l3)
(<= (CONTAINS ?l1 ?l3)
(exists (?l2)
(and (CONTAINS ?l1 ?l2)
(CONTAINS ?l2 ?l3)))))
and 1.3.2 ! (CONTAINS SOUTHERN-US TEXAS)
and 1.3.3 ! (CONTAINS TEXAS DALLAS)
|
3.12 Contexts and Modules
The final feature that we will illustrate in this section is the
PowerLoom context mechanism. PowerLoom organizes its knowledge into a
hierarchy of logical containers called “contexts”. A PowerLoom
context is either a “module”, a somewhat heavyweight object that
includes its own symbol table, or a “world”, a very lightweight object
designed for fast switching from one world to another. All contexts
inherit from a single root context. The most important feature of a
context is that a fact asserted into it is inherited by all contexts
below it. However, a “parent” context is unaware of any knowledge
entered into one of its descendants.
Here we concern ourselves only with modules. We first define a second
module, called alternate-business
, to be a subcontext of
our business
module, and then we switch into the new module:
| (defmodule "ALTERNATE-BUSINESS"
:includes "BUSINESS")
(in-module "ALTERNATE-BUSINESS")
|
Next, within the scope of the alternate-business
module, we will
create a new company. And just for good measure,
we will change the name of MegaSoft while we are at it:
| (assert (and (company web-phantoms)
(company-name web-phantoms "Web Phantoms, Inc.")))
(retract (company-name megasoft "MegaSoft, Inc."))
(assert (company-name megasoft "MegaZorch, Inc."))
|
First, here are pairs of companies and company names from the vantage
point of the Business
module:
| (in-module "BUSINESS")
(retrieve all (company-name ?x ?y))
⇒
There are 3 solutions:
#1: ?X=ACME-CLEANERS, ?Y="ACME Cleaners, LTD"
#2: ?X=MEGASOFT, ?Y="MegaSoft, Inc."
#3: ?X=MEGASOFT, ?Y="MegaSoft"
|
Now observe the same query executed from within the alternate Business
module:
| (in-module "ALTERNATE-BUSINESS")
(retrieve all (company-name ?x ?y))
⇒
There are 4 solutions:
#1: ?X=ACME-CLEANERS, ?Y="ACME Cleaners, LTD"
#2: ?X=MEGASOFT, ?Y="MegaZorch, Inc."
#3: ?X=WEB-PHANTOMS, ?Y="Web Phantoms, Inc."
#4: ?X=MEGASOFT, ?Y="MegaSoft"
|
We see that all facts pertaining to company names have inherited down
from the Business to the Alternate Business module, except for the
name for MegaSoft that we explicitly retracted. Also, the new
facts asserted within the Alternate Business module appear mixed in
with the inherited facts.
3.13 Equality Reasoning
PowerLoom makes the unique names assumption, so every two
different named logic constants are assumed to be different. For
example:
| (assert (= Fred Joe))
⇒
Derived both TRUE and FALSE for the proposition `|P#|FALSE'.
Clash occurred in module `|MDL|/PL-KERNEL-KB/PL-USER'.
(assert (= Fred Fred))
⇒
|P|TRUE
|
However, one can assert equality between skolems that represent function
terms as well as between a function term skolem and a regular constant.
For example:
| (deffunction age (?x ?y))
(assert (= (age Fred) (age Joe)))
(assert (= (age Fred) 10))
(retrieve (age Joe ?x))
⇒
There is 1 solution so far:
#1: ?X=10
|
So, if one needs to model named individuals where equality might be
asserted (e.g., to model a person with an alias) one has to resort
to using function terms. For example:
| (deffunction individual (?name ?i))
(assert (= (age (individual A)) 12))
(assert (= (individual A) (individual B)))
(retrieve (age (individual B) ?a))
⇒
There is 1 solution so far:
#1: ?A=12
|
3.14 Classification, Subsumption
3.15 Truth Maintenance
3.16 Inference Control
3.17 Keyword Axioms
3.18 Cardinality/Type Reasoning with Frame Predicates
3.19 Loom-to-PowerLoom
3.20 Deviations from KIF
3.21 Differences from Loom
3.22 Defaults
3.23 Sets, Lists, SETOFALL, KAPPA
This document was generated by Hans Chalupsky on January 6, 2023 using texi2html 1.82.