Learn

Sunday, 3 December 2017

How to Use PowerLoom APIs In Java Artificial Intelligence Framework Programming



Using the PowerLoom APIs in Java Programs:

             Once you interactively develop concepts, rules, and relations then it is likely that you may want to use them with PowerLoom in an embedded mode, making PowerLoom a part of your application. I will get you started with a few Java example programs. The source code for this chapter is in the subdirectory src-powerloom-reasoning.

               If you download the PowerLoom manual (a PDF file) from the PowerLoom web site, you will have the complete Java API documentation for the Java version of Power-Loom (there are also C++ and Common Lisp versions with separate documentation).I have found that I usually use just a small subset of the Java PowerLoom APIs and I have “wrapped” this subset in a wrapper class in the file PowerLoomUtils.java. We will use my wrapper class for the examples in the rest of this chapter.


My wrapper class has the follow public methods:

  • PowerLoomUtils() – constructor initializes the Java PowerLoom runtime system.
  • Load(String fpath) – load a source *.plm file.
  • ChangeModule(String workingModule) – set the current PowerLoom working module (“PL-USER” is the default module).
  • assertProposition(String proposition) – asserts a new proposition; for example:”(and (company c3) (company-name c3 n”Moms Groceryn”))”. Notethat quotation marks are escaped with a backslash character. You can also use single quote characters like: ”(and (company c3) (company-name c3 ’Moms Grocery’))” because I convert single quotes in my wrapper code.
  • createRelation(String relation, int arity) – create a new relation with a specifiedarity (number of “arguments”). For example you could create a relation “owns” with arity 2 and then assert “(owns Elaine ’Moms Grocery’)” – I usually do not use this API since I prefer to place relations (with rules) in a source code file ending in the extention *.plm.
  • doQuery(String query) – returns a list of results from a query. Each result in the list is itself a list. 
You will always want to work in an interactive PowerLoom console for writing and debugging PowerLoom models. I built the model in test.plm (in the subdirectory test data) interactively and we will use it here in an embedded Java example:


PowerLoomUtils plu = new PowerLoomUtils();
plu.load("test_data/test.plm");
plu.changeModule("BUSINESS");
plu.assertProposition(
"(and (company c1)" +
" (company-name c1 \"Moms Grocery\"))");
plu.assertProposition(
"(and (company c2)" +
" (company-name c2 \"IBM\"))");
plu.assertProposition(
"(and (company c3)" +
" (company-name c3 \"Apple\"))");
List answers = plu.doQuery("all ?x (company ?x)");
System.out.println(answers);
// answers: [[C3], [C2], [C1]]
answers = plu.doQuery(
"all (?x ?name)" +
" (and" +
" (company ?x)" +
" (company-name ?x ?name))");
System.out.println(answers);
// answers:
// [[C3, "Apple"],
// [C2, "IBM"],
// [C1, "Moms Grocery"]]
plu.createRelation("CEO", 2);
plu.assertProposition(
"(CEO \"Apple\" \"SteveJobs\")");
answers = plu.doQuery(
"all (?x ?name ?ceo)" +
" (and" +
" (company-name ?x ?name)" +
" (CEO ?name ?ceo))");
System.out.println(answers);
// answers: [[C3, "Apple", "SteveJobs"]]

I have added the program output produced by printing the value of the list variable “answers” as comments after each System.out.println call. In the wrapper API calls that take a string argument, I broke long strings over several lines for formatting to the width of a page; you would not do this in your own programs because of the cost of the extra string concatenation.

We will not look at the implementation of the PowerLoomUtils class – you can read the code if you are interested. That said, I will make a few commments on the Java PowerLoom APIs. The class PLI contains static methods for initializing the system, loading PowerLoom source files. Here are a few examples:

PLI.initialize();
PLI.load("test.plm", null);
PLI.sChangeModule("BUSINESS", null);

How to run PowerLoom Interactively in Java Artificial Intelligence Programming




Running PowerLoom:

We will experiment with PowerLoom concepts, relations, and rules in this section in an interactive command shell. I will introduce more examples of PowerLoom functionality for asserting instances of concepts, performing queries, loading PowerLoom source files, defining relations, using separate modules, and asking Power-Loom to explain the inference process that is used for query processing.

You can run PowerLoom using the command line interface by changing directory to the lib subdirectory from the ZIP file for this book and trying:


java -cp powerloom.jar:stella.jar \\
edu.isi.powerloom.PowerLoom

This starts the PowerLoom standalone system and prints a prompt that includes the name of the current module. The default module name is “PL-USER”. In the first example, when I enter the person concept at the interactive prompt then PowerLoom prints the result of the expression that just entered.

PL-USER |= (defconcept person)
|c|PERSON

PL-USER |= (defconcept parent (?p person))
|c|PARENT

PL-USER |= (defrelation parent-of
((?p1 parent) (?p2 person)))
|r|PARENT-OF

PL-USER |= (assert (person Ken))
|P|(PERSON KEN)

PL-USER |= (assert (person Mark))
|P|(PERSON MARK)

PL-USER |= (assert (parent-of Ken Mark))
|P|(PARENT-OF KEN MARK)

Now that we have entered two concepts, a test relation, and asserted a few facts, we
can look at an example of PowerLoom’s query language:

PL-USER |= (retrieve all ?p (person ?p))
There are 2 solutions:

#1: ?P=MARK
#2: ?P=KEN

PL-USER |= (retrieve all ?p (parent ?p))

There is 1 solution:
#1: ?P=KEN
PL-USER |=

The obvious point to note from this example is that we never specified that Ken was a parent; rather, PowerLoom deduced this from the parent-of relation.

PowerLoom’s command line system prompts you with the string “PL-USER —=“ and you can type any definition or query. Like Lisp, PowerLoom uses a prefix notation and expressions are contained in parenthesis. PowerLoom supports a module system for partitioning concepts, relations, functions, and rules into different sets and as previously mentioned “PL-USER” is the default module. PowerLoom modules can form a hierarchy, inheriting concepts, relations, and rules from parent modules.

The subdirectory test data contains the demo file business.plm written by Robert MacGregor that is supplied with the full PowerLoom distribution. You can load his complete example using:

PL-USER |= (load "../test_data/business.plm")

This is a good example because it demonstrates most of the available functionality of PowerLoom in a short 200 lines. When you are done reading this chapter, please take a few minutes to read through this example file since I do not list it here. There are a few things to notice in this example. Here we see a rule used to make the relation “contains” transitive:

(defrelation contains (

      (?l1 geographic-location)

           (?l2 geographic-location)))

(defrule transitive-contains (=> (and (contains ?l1 ?l2)
         (contains ?l2 ?l3))
          (contains ?l1 ?l3)))

The operator => means that if the first clause is true then so is the second. In English, this rule could be stated “if an instance i1 contains i2 and if instance i2 contains i3 then we can infer that i1 also contains i3.” To see how this rule works in practice, we can switch to the example module “BUSINESS” and find all locations contained inside another location:

PL-USER |= (in-module "BUSINESS")
BUSINESS |= (retrieve all
(?location1 ?location2)
(contains ?location1 ?location2))
There are 15 solutions:
#1: ?LOCATION1=SOUTHERN-US, ?LOCATION2=TEXAS
#2: ?LOCATION1=TEXAS, ?LOCATION2=AUSTIN
#3: ?LOCATION1=TEXAS, ?LOCATION2=DALLAS
#4: ?LOCATION1=UNITED-STATES, ?LOCATION2=SOUTHERN-US
#5: ?LOCATION1=GEORGIA, ?LOCATION2=ATLANTA
#6: ?LOCATION1=EASTERN-US, ?LOCATION2=GEORGIA
#7: ?LOCATION1=UNITED-STATES, ?LOCATION2=EASTERN-US
#8: ?LOCATION1=SOUTHERN-US, ?LOCATION2=DALLAS
#9: ?LOCATION1=SOUTHERN-US, ?LOCATION2=AUSTIN
#10: ?LOCATION1=UNITED-STATES, ?LOCATION2=DALLAS
#11: ?LOCATION1=UNITED-STATES, ?LOCATION2=TEXAS
#12: ?LOCATION1=UNITED-STATES, ?LOCATION2=AUSTIN
#13: ?LOCATION1=EASTERN-US, ?LOCATION2=ATLANTA
#14: ?LOCATION1=UNITED-STATES, ?LOCATION2=GEORGIA
#15: ?LOCATION1=UNITED-STATES, ?LOCATION2=ATLANTA
BUSINESS |=

Here we have fifteen solutions even though there are only seven “contains” relations asserted in the business.plm file – the other eight solutions were inferred. In addition to the “retrieve” function that finds solutions matching a query you can also use the “ask” function to determine if a specified relation is true; for example:

BUSINESS |= (ask (contains UNITED-STATES DALLAS))
TRUE
BUSINESS |=

For complex queries you can use the “why” function to see how PowerLoom solved the last query:

BUSINESS |= (ask (contains southern-us dallas))
TRUE
BUSINESS |= (why)
1 (CONTAINS ?location1 ?location2)
follows by Modus Ponens
with substitution {?l1/SOUTHERN-US, ?l3/DALLAS,
?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 DALLAS)
BUSINESS |=

By default the explanation facility is turned off because it causes PowerLoom to run more slowly; it was turned on in the file business.plm using the statement: (set-feature justifications)