|
From: <tom...@us...> - 2008-04-20 16:47:45
|
Revision: 1230
http://jason.svn.sourceforge.net/jason/?rev=1230&view=rev
Author: tomklapiscak
Date: 2008-04-20 09:47:30 -0700 (Sun, 20 Apr 2008)
Log Message:
-----------
Given an incoming trigger, t, suppose we generalise to an SE-Plan, p, when looking for a relevant plan to deal with t.
The special variables JASDL_TG_CAUSE_RETAIN_ANNOTS and JASDL_TG_CAUSE are unified within the unifier of the intention that p is pushed onto
with t (including all annotations) and t with all annotations but "o" dropped. Has already proved to be a useful mechanism in the commerce example.
SE-Plans are now "inserted into" the plan library (in fact just the list of candidate SE-Plans returned) in order of generality (most specific first).
The algorithm to determine whether the trigger of one SE-Plan is more specific than another also supports arbitrarily nested SE-Literals.
Individuals are only instantiated under the enclosing SE-Literal's ontology if no reference to the individual (i.e. it's functor only) can be found across all ontologies known to the agent. In this sense, individuals are global across ontologies. TODO: is this safe? what if we want to reference two individuals by the same functor, but different label (i.e. ontology)? Qualify individuals with the [o(...)] annotation perhaps?
Fixed bug in jasdl.define_class. Abolishes defined class AFTER expression has been parsed in case the class definition uses a previously defined class by the same name within it.
Manchester OWL syntax renderers now renders class expressions in "normal form" (NsPrefix and URI short form providers extend Normalising short form provider that detects run-time defined classes and substitutes them for their renderings in terms of schema-defined classes). Both "anon" outgoing message annotations and classes renderings produced by jasdl.ia.get_class_definition are now inherently in normal form (the latter solves the thorny issue of run-time defined classes being defined in terms of themselves). Common#normaliseExpression deprecated since it is no longer needed.
Problem with Jason + JASDL - annotations of selected events added to triggers of intended means plan clones. Sometimes results in SE-Literals with multiple "o" annotations - hacked for now (last "o" removed).
jasdl.ia.define_class now removes assertions involving abolished definitions.
Continuing work on commerce example.
jasdl.ia.get_unique_individual now produces an individual name guaranteed to be unique across entire agent society (by prefixing identifier with agent name).
Modified Paths:
--------------
trunk/applications/jasdl-owlapi/README
trunk/applications/jasdl-owlapi/examples/commerce/bin/build.xml
trunk/applications/jasdl-owlapi/examples/commerce/commerce.mas2j
trunk/applications/jasdl-owlapi/examples/commerce/onts/commerce.owl
trunk/applications/jasdl-owlapi/examples/commerce/onts/society.owl
trunk/applications/jasdl-owlapi/examples/commerce/src/asl/customer.asl
trunk/applications/jasdl-owlapi/examples/commerce/src/asl/pa.asl
trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/CommerceEnvironment.java
trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/CommerceModel.java
trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelCustomer.java
trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelShop.java
trunk/applications/jasdl-owlapi/src/jasdl/JASDLParams.java
trunk/applications/jasdl-owlapi/src/jasdl/architecture/JASDLAgArch.java
trunk/applications/jasdl-owlapi/src/jasdl/asSemantics/JASDLAgent.java
trunk/applications/jasdl-owlapi/src/jasdl/asSemantics/JASDLAgentConfigurator.java
trunk/applications/jasdl-owlapi/src/jasdl/asSyntax/JASDLPlanLibrary.java
trunk/applications/jasdl-owlapi/src/jasdl/asSyntax/SEPlan.java
trunk/applications/jasdl-owlapi/src/jasdl/bb/JASDLBeliefBase.java
trunk/applications/jasdl-owlapi/src/jasdl/bridge/DLUnifier.java
trunk/applications/jasdl-owlapi/src/jasdl/bridge/JASDLOntologyManager.java
trunk/applications/jasdl-owlapi/src/jasdl/bridge/factory/AxiomToSELiteralConverter.java
trunk/applications/jasdl-owlapi/src/jasdl/bridge/factory/SELiteralToAxiomConverter.java
trunk/applications/jasdl-owlapi/src/jasdl/bridge/protocol/IncomingProtocolProcessingStrategy.java
trunk/applications/jasdl-owlapi/src/jasdl/bridge/protocol/OutgoingProtocolProcessingStrategy.java
trunk/applications/jasdl-owlapi/src/jasdl/bridge/protocol/ProtocolProcessor.java
trunk/applications/jasdl-owlapi/src/jasdl/bridge/seliteral/SELiteral.java
trunk/applications/jasdl-owlapi/src/jasdl/bridge/seliteral/SELiteralDataPropertyAssertion.java
trunk/applications/jasdl-owlapi/src/jasdl/env/JASDLEnvironment.java
trunk/applications/jasdl-owlapi/src/jasdl/ia/define_class.java
trunk/applications/jasdl-owlapi/src/jasdl/ia/get_anonymous_individual.java
trunk/applications/jasdl-owlapi/src/jasdl/ia/get_class_definition.java
trunk/applications/jasdl-owlapi/src/jasdl/ia/get_individual.java
trunk/applications/jasdl-owlapi/src/jasdl/util/owlapi/rendering/NsPrefixOWLObjectShortFormProvider.java
trunk/applications/jasdl-owlapi/src/jasdl/util/owlapi/rendering/URIOWLObjectShortFormProvider.java
Added Paths:
-----------
trunk/applications/jasdl-owlapi/examples/commerce/src/asl/shop.asl
trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelCustomerListener.java
trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/ui/
trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/ui/customer/
trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/ui/customer/CustomerUIFrame.java
trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/ui/customer/CustomerUIPanel.java
trunk/applications/jasdl-owlapi/src/jasdl/test/JASDLBeliefBaseTest.java
trunk/applications/jasdl-owlapi/src/jasdl/util/JASDLCommon.java
trunk/applications/jasdl-owlapi/src/jasdl/util/owlapi/parsing/NsPrefixOWLEntityChecker.java
trunk/applications/jasdl-owlapi/src/jasdl/util/owlapi/rendering/NormalisingOWLObjectShortFormProvider.java
Removed Paths:
-------------
trunk/applications/jasdl-owlapi/src/jasdl/test/JasdlBeliefBaseTest.java
trunk/applications/jasdl-owlapi/src/jasdl/util/Common.java
trunk/applications/jasdl-owlapi/src/jasdl/util/owlapi/parsing/NSPrefixOWLEntityChecker.java
Modified: trunk/applications/jasdl-owlapi/README
===================================================================
--- trunk/applications/jasdl-owlapi/README 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/README 2008-04-20 16:47:30 UTC (rev 1230)
@@ -20,4 +20,18 @@
Please refer to /trunk/jason/applications/jasdl-owlapi/examples/travel_agent/config.mas2j for an example of how to configure JASDL agents.
-Thank you for your interest in JASDL!
\ No newline at end of file
+*** Known issues ***
+
+The -+ operator does not function properly. Until this problem is fixed the operation must be performed in two steps as shown here:
+-+a;
+becomes:
+-a;
++a;
+
+When TG is applied to complex test goals, unifications do not propagate correctly
+
+Trigger generalisation is not properly applied when searching for an suitable failure event for intended means that are not in the top level of an intention.
+
+
+
+Thank you for your interest in JASDL!
Modified: trunk/applications/jasdl-owlapi/examples/commerce/bin/build.xml
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/bin/build.xml 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/examples/commerce/bin/build.xml 2008-04-20 16:47:30 UTC (rev 1230)
@@ -5,7 +5,7 @@
This file was generated by Jason ?
http://jason.sf.net
- April 18, 2008 - 18:12:11
+ April 20, 2008 - 17:28:53
-->
<project name ="commerce"
Modified: trunk/applications/jasdl-owlapi/examples/commerce/commerce.mas2j
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/commerce.mas2j 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/examples/commerce/commerce.mas2j 2008-04-20 16:47:30 UTC (rev 1230)
@@ -7,13 +7,13 @@
environment: commerce.env.CommerceEnvironment
agents:
- shop1
+ shop
[
jasdl_ontologies="c,s",
jasdl_c_uri="/onts/commerce.owl",
jasdl_s_uri="/onts/society.owl"
]
- #1
+ #2
agentArchClass jasdl.architecture.JASDLAgArch
agentClass jasdl.asSemantics.JASDLAgent
beliefBaseClass jasdl.bb.JASDLBeliefBase;
Modified: trunk/applications/jasdl-owlapi/examples/commerce/onts/commerce.owl
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/onts/commerce.owl 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/examples/commerce/onts/commerce.owl 2008-04-20 16:47:30 UTC (rev 1230)
@@ -75,10 +75,17 @@
+ <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/commerce.owl#includedIn -->
+
+ <owl:ObjectProperty rdf:about="#includedIn">
+ <owl:inverseOf rdf:resource="#includes"/>
+ </owl:ObjectProperty>
+
+
+
<!-- http://www.dur.ac.uk/t.g.klapiscak/onts/commerce.owl#includes -->
<owl:ObjectProperty rdf:about="#includes">
- <rdf:type rdf:resource="&owl;TransitiveProperty"/>
<rdfs:domain rdf:resource="#Order"/>
<rdfs:range rdf:resource="#Purchase"/>
</owl:ObjectProperty>
@@ -116,6 +123,16 @@
+ <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/commerce.owl#hasProductDescription -->
+
+ <owl:DatatypeProperty rdf:about="#hasProductDescription">
+ <rdf:type rdf:resource="&owl;FunctionalProperty"/>
+ <rdfs:domain rdf:resource="#Purchase"/>
+ <rdfs:range rdf:resource="&xsd;string"/>
+ </owl:DatatypeProperty>
+
+
+
<!-- http://www.dur.ac.uk/t.g.klapiscak/onts/commerce.owl#hasQuantity -->
<owl:DatatypeProperty rdf:about="#hasQuantity">
@@ -126,6 +143,15 @@
+ <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/commerce.owl#hasShopDescription -->
+
+ <owl:DatatypeProperty rdf:about="#hasShopDescription">
+ <rdfs:domain rdf:resource="#Purchase"/>
+ <rdfs:range rdf:resource="&xsd;string"/>
+ </owl:DatatypeProperty>
+
+
+
<!-- http://www.dur.ac.uk/t.g.klapiscak/onts/commerce.owl#hasVolume -->
<owl:DatatypeProperty rdf:about="#hasVolume">
@@ -339,31 +365,6 @@
- <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/commerce.owl#InStock -->
-
- <owl:Class rdf:about="#InStock">
- <owl:equivalentClass>
- <owl:Class>
- <owl:intersectionOf rdf:parseType="Collection">
- <rdf:Description rdf:about="#Product"/>
- <owl:Restriction>
- <owl:onProperty rdf:resource="#hasInStock"/>
- <owl:someValuesFrom>
- <rdf:Description>
- <rdf:type rdf:resource="&owl;DataRange"/>
- <owl11:minInclusive rdf:datatype="&xsd;int">1</owl11:minInclusive>
- <owl11:onDataRange rdf:resource="&xsd;int"/>
- </rdf:Description>
- </owl:someValuesFrom>
- </owl:Restriction>
- </owl:intersectionOf>
- </owl:Class>
- </owl:equivalentClass>
- <rdfs:subClassOf rdf:resource="#Product"/>
- </owl:Class>
-
-
-
<!-- http://www.dur.ac.uk/t.g.klapiscak/onts/commerce.owl#Ingredient -->
<owl:Class rdf:about="#Ingredient">
Modified: trunk/applications/jasdl-owlapi/examples/commerce/onts/society.owl
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/onts/society.owl 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/examples/commerce/onts/society.owl 2008-04-20 16:47:30 UTC (rev 1230)
@@ -57,23 +57,20 @@
- <!--
- ///////////////////////////////////////////////////////////////////////////////////////
- //
- // Data properties
- //
- ///////////////////////////////////////////////////////////////////////////////////////
- -->
+ <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#ownedBy -->
+ <owl:ObjectProperty rdf:about="#ownedBy">
+ <rdf:type rdf:resource="&owl;FunctionalProperty"/>
+ </owl:ObjectProperty>
- <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#isBusy -->
+ <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#owns -->
- <owl:DatatypeProperty rdf:about="#isBusy">
- <rdf:type rdf:resource="&owl;FunctionalProperty"/>
- <rdfs:range rdf:resource="&xsd;int"/>
- </owl:DatatypeProperty>
+ <owl:ObjectProperty rdf:about="#owns">
+ <rdf:type rdf:resource="&owl;InverseFunctionalProperty"/>
+ <owl:inverseOf rdf:resource="#ownedBy"/>
+ </owl:ObjectProperty>
@@ -96,6 +93,22 @@
+ <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#Butchers -->
+
+ <owl:Class rdf:about="#Butchers">
+ <rdfs:subClassOf rdf:resource="#Shop"/>
+ </owl:Class>
+
+
+
+ <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#Company -->
+
+ <owl:Class rdf:about="#Company">
+ <rdfs:subClassOf rdf:resource="&owl;Thing"/>
+ </owl:Class>
+
+
+
<!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#Customer -->
<owl:Class rdf:about="#Customer">
@@ -114,6 +127,14 @@
+ <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#GreenGrocers -->
+
+ <owl:Class rdf:about="#GreenGrocers">
+ <rdfs:subClassOf rdf:resource="#Shop"/>
+ </owl:Class>
+
+
+
<!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#PA -->
<owl:Class rdf:about="#PA">
@@ -134,9 +155,9 @@
- <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#Tesco -->
+ <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#Supermarket -->
- <owl:Class rdf:about="#Tesco">
+ <owl:Class rdf:about="#Supermarket">
<rdfs:subClassOf rdf:resource="#Shop"/>
</owl:Class>
@@ -185,18 +206,13 @@
<!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#delivery_van1 -->
- <DeliveryVan rdf:about="#delivery_van1">
- <isBusy rdf:datatype="&xsd;int">0</isBusy>
- </DeliveryVan>
+ <DeliveryVan rdf:about="#delivery_van1"/>
<!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#delivery_van2 -->
- <DeliveryVan rdf:about="#delivery_van2">
- <isBusy rdf:datatype="&xsd;int">0</isBusy>
- <isEmployedBy rdf:resource="#shop1"/>
- </DeliveryVan>
+ <DeliveryVan rdf:about="#delivery_van2"/>
@@ -220,12 +236,28 @@
<!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#shop1 -->
- <Tesco rdf:about="#shop1">
+ <Supermarket rdf:about="#shop1">
<employs rdf:resource="#delivery_van1"/>
- </Tesco>
+ <ownedBy rdf:resource="#tescos_inc"/>
+ </Supermarket>
+ <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#shop2 -->
+
+ <Butchers rdf:about="#shop2">
+ <employs rdf:resource="#delivery_van2"/>
+ <ownedBy rdf:resource="#tescos_inc"/>
+ </Butchers>
+
+
+
+ <!-- http://www.dur.ac.uk/t.g.klapiscak/onts/society.owl#tescos_inc -->
+
+ <Company rdf:about="#tescos_inc"/>
+
+
+
<!--
///////////////////////////////////////////////////////////////////////////////////////
//
@@ -237,15 +269,17 @@
<rdf:Description>
<rdf:type rdf:resource="&owl;AllDifferent"/>
<owl:distinctMembers rdf:parseType="Collection">
+ <rdf:Description rdf:about="#pa3"/>
+ <rdf:Description rdf:about="#customer3"/>
+ <rdf:Description rdf:about="#delivery_van1"/>
<rdf:Description rdf:about="#pa2"/>
<rdf:Description rdf:about="#shop1"/>
<rdf:Description rdf:about="#pa1"/>
+ <rdf:Description rdf:about="#customer1"/>
<rdf:Description rdf:about="#customer2"/>
- <rdf:Description rdf:about="#customer1"/>
+ <rdf:Description rdf:about="#tescos_inc"/>
<rdf:Description rdf:about="#delivery_van2"/>
- <rdf:Description rdf:about="#delivery_van1"/>
- <rdf:Description rdf:about="#customer3"/>
- <rdf:Description rdf:about="#pa3"/>
+ <rdf:Description rdf:about="#shop2"/>
</owl:distinctMembers>
</rdf:Description>
</rdf:RDF>
Modified: trunk/applications/jasdl-owlapi/examples/commerce/src/asl/customer.asl
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/src/asl/customer.asl 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/examples/commerce/src/asl/customer.asl 2008-04-20 16:47:30 UTC (rev 1230)
@@ -6,36 +6,44 @@
* - the structural information in the ontology gives us a richer palette for semantic matching over and above that available through
* e.g. synonym matching.
* Assuming central repository of agents and their types (society.owl schema)
+ * IDs are propagated through annotations to match product request brands with quantities
*/
-!behave.
-
- // need to use SE-Literals to take advantage of syntactic translation
-+!behave
- <-
- .random(Rand);
- .wait(Rand*2000);
- .my_name(Me);
- jasdl.ia.define_class(employedPA, "s:pA and s:isEmployedBy value s:", Me);
- ?employedPA(PA)[o(self)];
- !order(PA, Me, bread(_)[o(c)], 1);
- !order(PA, Me, milk(_)[o(c)], 1);
- !order(PA, Me, bread(hovis)[o(c)], 1);
- .send(PA, achieve, confirm_order(Me)).
+
++ui_product_request(ProductDescription, ShopDescription, Qty)[source(percept)]
+ <-
+ .print("UI recieved request");
+ // Get a PA employed by me
+ ?employs(PA);
-+!order(PA, Order, Product, Qty)
+ // Explicitly discard the percept - in case an identical request comes in next perception cycle (we still want to catch it)
+ -ui_product_request(ProductDescription, ShopDescription, Qty)[source(percept)];
+
+ // Must be defined locally in order to take advantage of syntactic translation.
+ // If these were simply sent as string to PA and this agent had different entity aliases / ontology labels
+ // then the PA would not be able to understand the request.
+
+ jasdl.ia.define_class(suitableProduct, ProductDescription);
+ jasdl.ia.define_class(suitableShop, ShopDescription);
+
+
+ // Request a suitable brand from the PA
+ jasdl.ia.send(PA, achieve, suitable(suitableProduct(_)[o(self)], suitableShop(_)[o(self)], Qty)).
+
+
++!product(Brand)[o(c), source(PA), approve, id(ID)] :
+ employs(PA)
<-
- .send(PA, achieve, order(Order, Product, Qty));
- Confirmed = confirmed(Order, Brand, Qty)[source(PA)];
- .concat("+", Confirmed, WaitConfirmed); .wait(WaitConfirmed);
- -Confirmed.
+ approve(Brand);
+ .send(PA, tell, approved(product(Brand)[o(c), id(ID)])).
-+order_complete(Order)[source(Shop)]
+-!product(Brand)[o(c), source(PA), approve, id(ID)] :
+ employs(PA)
<-
- -order_complete(Order)[source(Shop)];
- !behave.
+ .send(PA, tell, rejected(product(Brand)[o(c), id(ID)])).
+
Modified: trunk/applications/jasdl-owlapi/examples/commerce/src/asl/pa.asl
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/src/asl/pa.asl 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/examples/commerce/src/asl/pa.asl 2008-04-20 16:47:30 UTC (rev 1230)
@@ -2,30 +2,130 @@
-+!order(Order, Product, Qty)[source(Employer)] : isEmployedBy(Employer)
++!suitable(ProductClass, ShopClass, Qty)[source(Customer)] :
+ isEmployedBy(Customer)
+ <-
+ ?hasOrder(Customer, Order)[o(c)];
+ .print(Order);
+
+ ?ShopClass;
+ jasdl.ia.get_individual(ShopClass, Shop);
+
+
+ // Generate a unique (guaranteed across entire agent society) request identifier (individual)
+ jasdl.ia.get_anonymous_individual(ID);
+
+ jasdl.ia.get_class_definition(ShopClass, ShopDescription);
+ jasdl.ia.get_class_definition(ProductClass, ProductDescription);
+
+ // Add the condition that the product must be in stock (this is not something the customer should be concerned with)
+ .concat("(",ProductDescription,") and c:hasInStock some integer [ >= ",Qty,"]",ProductDescriptionInStock);
+
+ // Parse the product description into a class
+ jasdl.ia.define_class(productInStock, ProductDescriptionInStock);
+
+ .print("Asking ",Shop,":", ProductDescriptionInStock);
+
+ // Ask for all brands that match these criteria
+ //jasdl.ia.send(Shop, achieve, suitable(description(Brand)[o(self)])[id(ID)]).
+ jasdl.ia.send(Shop, askOne, productInStock(Brand)[o(self), id(ID)]);
+
+ +purchase(ID)[o(c)];
+ +includes(Order, ID)[o(c)];
+ +hasQuantity(ID, Qty)[o(c)];
+ +hasProductDescription(ID, ProductDescription)[o(c)];
+ +hasShopDescription(ID, ShopDescription)[o(c)].
+
+
++product(Brand)[o(c), id(ID), source(Shop)] :
+ shop(Shop)[o(s)] // from a known shop
<-
- ?shop(Shop)[o(s)];
- jasdl.ia.send(Shop, askOne, hasOrder(Employer, Order)[o(c)], hasOrder(Employer, Order)[o(c)]);
- // get me a brand that is in stock
- jasdl.ia.get_class_definition(Product, ProductDefinition);
- jasdl.ia.define_class(productInStock, ProductDefinition);//, " and (c:hasInStock some integer [>= ",Qty ," ])");
- jasdl.ia.send(Shop, askOne, productInStock(Brand)[o(self)], product(Brand)[o(c)]);
- .print("Brand name: ", Brand);
- /* Check against medical requirements of customer */
- .send(Shop, achieve, add_to_order(Order, Brand, Qty));
- Confirmed = confirmed(Order, Brand, Qty)[source(Shop)];
- .concat("+", Confirmed, WaitConfirmed); .wait(WaitConfirmed);
- -Confirmed;
- .send(Employer, tell, Confirmed).
+ !approve(product(Brand)[o(c), id(ID)]).
++referral(Referred)[id(ID), source(Shop)] :
+ shop(Referred)[o(s)] &
+ shop(Shop)[o(s)]
+ <-
+ -referral(Referred)[id(ID), source(Shop)];
+ .print("referred to ", Referred).
-+!confirm_order(Order)[source(Employer)] : isEmployedBy(Employer)
++failed[id(ID), source(Shop)] :
+ shop(Shop)[o(s)]
<-
- ?shop(Shop)[o(s)];
- .send(Shop, achieve, confirm_order(Order)).
+ !abolish_purchase(ID);
+ .print("Failed!").
++!approve(A)
+ <-
+
+ // get my employer (rule expressed in terms of SE-Literals, see common/society.asl)
+ ?isEmployedBy(Employer);
+
+ .my_name(Me);
+ .add_annot(A, source(Me), B);
+
+ // ask customer for approval
+ // We add the approve annotation to isolate this
+ // type of query from others
+ .add_annot(B, approve, C);
+ .send(Employer, achieve, C).
+
++approved(product(Brand)[o(c), id(ID)])[source(Employer)] :
+ isEmployedBy(Employer)
+ <-
+ +hasBrand(ID, Brand)[o(c)];
+ .print("Approved ", Brand, " (id: ", ID, ")").
+
+@sdfdsf[breakpoint]
++rejected(product(Brand)[o(c), id(ID)])[source(Employer)] :
+ isEmployedBy(Employer)
+ <-
+ ?includedIn(ID, Order)[o(c)];
+ ?hasQuantity(ID, Qty)[o(c)];
+ ?hasProductDescription(ID, ProductDescription)[o(c)];
+ ?hasShopDescription(ID, ShopDescription)[o(c)];
+
+ !abolish_purchase(ID);
+
+ .concat("(",ProductDescription,") and not {c:",Brand,"}", AmmendedProductDescription);
+ .print("Rejected ", Brand, " (id: ", ID, ")");
+
+ // We need this individual to be instantiated in our own commerce ontology
+ // to allow us to safely refer to it in class expressions
+ //+product(Brand)[o(c)];
+
+ // Get the class describing the type of product, adding the additional requirement that it
+ // also not be the individual rejected by the customer
+ jasdl.ia.define_class(ammendedProductClass, AmmendedProductDescription);
+
+ // Get the class describing the desired type of shop, without changing any requirements
+ jasdl.ia.define_class(shopClass, ShopDescription);
+
+ .print("Rejected ", Brand, ". Retry with shop=", ShopDescription, " and product=", AmmendedProductDescription);
+
+ // We use the same achieve goal used by a customer here, effectively emulating a customer request, but with the ammended product
+ // description, given the customer's rejection
+ !suitable(ammendedProductClass(_)[o(self)], shopClass(_)[o(self)], Qty)[source(Employer)].
++!abolish_purchase(ID) :
+ purchase(ID)[o(c)]
+ <-
+ -hasProductDescription(ID, _)[o(c), source(self)];
+ -hasShopDescription(ID, _)[o(c), source(self)];
+ -includedIn(ID, _)[o(c), source(self)];
+ -hasQuantity(ID, _)[o(c), source(self)];
+ -purchase(ID)[o(c), source(self)].
+
+
+/* Opening a new order.
+ * Will only be generated with no order can be found (or at least none by this name)
+ */
++?hasOrder(Customer, Order)[o(c)] :
+ isEmployedBy(Customer)
+ <-
+ jasdl.ia.get_anonymous_individual(Order);
+ +hasOrder(Customer, Order)[o(c)].
Added: trunk/applications/jasdl-owlapi/examples/commerce/src/asl/shop.asl
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/src/asl/shop.asl (rev 0)
+++ trunk/applications/jasdl-owlapi/examples/commerce/src/asl/shop.asl 2008-04-20 16:47:30 UTC (rev 1230)
@@ -0,0 +1,240 @@
+{include("common/society.asl")}
+
++!kqml_received(Sender, askOne, Content[o(O), id(ID)], MsgId) :
+ pA(PA)[o(s)]
+ <-
+ .add_annot(Content, source(Sender), X);
+ .add_annot(X, o(O), Y);
+ .add_annot(Y, id(ID), Z);
+ ?Z.
+
+
+
+
+
+
+
+
++?product(Brand)[o(c), id(ID), source(PA)] : JASDL_TG_CAUSE
+ <-
+ //.add_annot(JASDL_TG_CAUSE, id(ID), Response);
+ //.send(PA, tell, Response).
+ jasdl.ia.get_individual(JASDL_TG_CAUSE, Brand);
+ .print("Sending ", JASDL_TG_CAUSE);
+ .send(PA, tell, product(Brand)[o(c), id(ID)]).
+
+/** Plans dealing with a failure to find a suitable product within the belief-base of this agent */
+
++?thing(Brand)[o(owl), id(ID), source(PA)] :
+ not JASDL_TG_CAUSE
+ <-
+ .print("Requested unknown product, moreover, no other shops in this company can be identified to potentially service this request");
+ .send(PA, tell, failure[id(ID)]).
+
++?product(Brand)[o(c), id(ID), source(PA)] :
+ not JASDL_TG_CAUSE &
+ .my_name(Me) &
+ ownedBy(Me, Owner)[o(s)] &
+ jasdl.ia.define_class(mightStock, "s:shop and s:ownedBy value s:",Owner," and (not {s:",Me,"})") &
+ mightStock(Shop)[o(self)]
+ <-
+ .print("Requested unknown product, attempting to refer to any other shop owned by this company");
+ .send(PA, tell, referral(Shop)[id(ID)]).
+
+/**
+ * No suitable product has been found in this agent's belief base. However,
+ * because it is a type of meat product, it might be worth looking for butchers
+ * owned by this company and referring to PA to them (if any are known).
+ */
++?meat(Brand)[o(c), id(ID), source(PA)] :
+ not JASDL_TG_CAUSE &
+ .my_name(Me) &
+ ownedBy(Me, Owner)[o(s)] &
+ jasdl.ia.define_class(mightStock, "s:butchers and s:ownedBy value s:",Owner," and (not {s:",Me,"})") &
+ mightStock(Butchers)[o(self)]
+ <-
+ .print("Requested unknown meat product, attempting to refer to a butchers owned by this company");
+ .send(PA, tell, referral(Butchers)[id(ID)]).
+
+/****************************************************************/
+
+
+
+
+
++!add_to_order(Order, Brand, Qty)[source(PA)] :
+ product(Brand)[o(c)] & // check known product brand
+ hasCustomer(Order, Customer)[o(c)] & employs(Customer, PA)[o(s)] & // check PA is authorised to speak on behalf of customer whose order it is
+ hasInStock(Brand, StockLevel)[o(c)] & StockLevel>=Qty // check we have enough stock
+ <-
+
+ // get a unique purchase identifier
+ jasdl.ia.get_anonymous_individual(PID);
+
+ // add purchase
+ +purchase(PID)[o(c)];
+ +includes(Order, PID)[o(c)];
+ +hasBrand(PID, Brand)[o(c)];
+ +hasQuantity(PID, Qty)[o(c)];
+ .send(PA, tell, confirmed(Order, Brand, Qty)).
+
+
+
++!confirm_order(Order)[source(PA)] :
+ hasCustomer(Order, Customer)[o(c)] &
+ employs(Customer, PA)[o(s)]
+ <-
+ !deploy(Order);
+ !allocate_available(Van);
+ !recall(Van);
+ !load(Order, Van);
+ !dispatch(Order, Van);
+ !unload(Order, Van);
+ +available(Van);
+ .abolish(includes(Order, _)[o(c)]);
+ .send(Customer, tell, order_complete(Order)).
+
+
+
+@available[atomic]
++!allocate_available(Van)
+ <-
+ ?available(Van)[source(_)];
+ -available(Van)[source(_)].
+
++?available(Van)
+ <-
+ .concat("+",available(Van)[source(_)], WaitFor);
+ .wait(WaitFor);
+ ?available(Van)[source(_)].
+
++!load(Order, Van) : .my_name(Me) & inVicinityOf(Van)
+ <-
+ -hasPosition(Van, X, Y)[source(Van)];
+ .findall(PID, includes(Order, PID)[o(c)], PIDs);
+ .send(Van, achieve, load(PIDs));
+ L=loading_complete[source(Van)];
+ .concat("+", L, WaitFor);
+ .wait(WaitFor);
+ -L.
+
++!unload(Order, Van)
+ <-
+ .findall(PID, includes(Order, PID)[o(c)], PIDs);
+ .send(Van, achieve, unload(PIDs));
+ L=unloading_complete[source(Van)];
+ .concat("+", L, WaitFor);
+ .wait(WaitFor);
+ -L.
+
++!recall(Van)
+ <-
+ .my_name(Me);
+ ?hasPosition(Me, MX, MY);
+ !hasPosition(Van, MX, MY).
+
++!dispatch(Order, Van)
+ <-
+ ?hasCustomer(Order, Customer)[o(c)];
+ .send(Customer, askOne, hasPosition(Customer, X, Y), hasPosition(Customer, X, Y));
+ !hasPosition(Van, X, Y).
+
+
++!hasPosition(Van, X, Y) : L=hasPosition(Van, X, Y) & not L
+ <-
+ .send(Van, achieve, hasPosition(Van, X, Y));
+ .concat("+", L[source(Van)], WaitFor);
+ .wait(WaitFor);
+ -L.
+
++!hasPosition(Van, X, Y) : L=hasPosition(Van, X, Y) & L.
+
+
+
+
++!deploy([]).
++!deploy([Purchase|Purchases])
+ <-
+ ?hasBrand(Purchase, Brand)[o(c)];
+ ?hasQuantity(Purchase, Qty)[o(c)];
+ deploy(Purchase, Brand, Qty);
+ .print("Deploying crate", Purchase);
+ !deploy(Purchases).
++!deploy(Order)
+ <-
+ .findall(PID, includes(Order, PID)[o(c)], PIDs);
+ !deploy(PIDs).
+
+
+
+
++?details(Brand, Details) : product(PID)[o(c)]
+ <-
+ ?hasPrice(Brand, Price)[o(c)];
+ ?hasInStock(Brand, StockLevel)[o(c)];
+ jasdl.ia.get_types(Brand, self, true, Types);
+ .concat("Brand Name=", Brand, ", Stock level=", StockLevel, ", Price=", ", Classifications=", Types, Price, Details).
+
+/* Failed to get details. Reason: No price listed for product type */
+-?details(Brand, Details) : product(Brand)[o(c)] & not hasPrice(Brand, Price)
+ <-
+ .concat("No price listed for product ", Brand, Details).
+
++!print_details(Brand) : product(Brand)[o(c)]
+ <-
+ ?details(Brand, Details);
+ .print(Details).
+
+
+
+
+/* Local Prices */
+
+
+
+/* We trust the delivery_agent when it informs of a product removal */
+/*
+-hovis(PID)[o(c)]
+ <-
+ -product(PID)[o(c), source(self)];
+ ?details(PID, Details);
+ .print("Sold ", Details).
+*/
+
+
+/* Gets this shop's price for a class of individuals */
+// TODO: jasdl.ia.seliteral(Literal)
+/* SAFELY allowing classes to be subjects of properties*/
+/*
+Deprecated, prices are obtained statically
++?hasPrice(PID, Price) : .atom(PID)
+ <-
+ .print("Get price of ", PID);
+ ?hasPrice(product(PID)[o(c)], Price). // <- why doesn't this work?
+
+
+
+
++!hasPrice(product(PID)[o(c)], Price) // <- note: not semantically-enriched
+ <-
+ .findall(product(PID)[o(c)], product(PID)[o(c)], Groundings);
+ .print("Setting price to ",Price," for ", Groundings);
+ !hasPrice(Groundings, Price).
+
++!hasPrice([Grounding | Groundings], Price)
+ <-
+ jasdl.ia.get_individual(Grounding, PID);
+ +hasPrice(PID, Price)[o(c)]; // <- note: semantically-enriched
+ !hasPrice(Groundings, Price).
+
++!hasPrice([], _).
+
+*/
+
+
+/*
+ Doesn't work, since concat creates string term and so includes quotation marks which are not valid URI characters
+ .findall(ID, includes(Order, ID)[o(c)], IDs);
+ .length(IDs, MaxID);
+ .concat("purchase_", Order, "_", MaxID, PID);
+ */
Modified: trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/CommerceEnvironment.java
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/CommerceEnvironment.java 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/CommerceEnvironment.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -1,7 +1,7 @@
package commerce.env;
// Environment code for project commerce.mas2j
-import static jasdl.util.Common.getCurrentDir;
+import static jasdl.util.JASDLCommon.getCurrentDir;
import jasdl.bridge.factory.AliasFactory;
import jasdl.bridge.mapping.aliasing.Alias;
import jasdl.bridge.mapping.aliasing.DecapitaliseMappingStrategy;
@@ -21,14 +21,17 @@
import java.net.URI;
import java.util.Arrays;
import java.util.List;
+import java.util.Vector;
import java.util.logging.Logger;
import commerce.env.model.CommerceModel;
import commerce.env.model.ModelAgent;
+import commerce.env.model.ModelCustomer;
import commerce.env.model.ModelDeliveryVan;
import commerce.env.model.ModelObject;
import commerce.env.model.ModelShop;
import commerce.exception.ModelAgentException;
+import commerce.ui.customer.CustomerUIFrame;
@@ -38,7 +41,7 @@
* @author tom
*
*/
-public class CommerceEnvironment extends JASDLEnvironment {
+public class CommerceEnvironment extends JASDLEnvironment{
public Atom s = new Atom("s");
@@ -57,11 +60,20 @@
super.init(args);
model = new CommerceModel(new Dimension(20, 20), this);
+
view = new CommerceView(model);
+
+ CustomerUIFrame customerUIFrame = new CustomerUIFrame(this);
+ // for each customer set-up a UI Panel
+ for(ModelObject o : model.getObjects()){
+ if(o instanceof ModelCustomer){
+ customerUIFrame.addCustomer((ModelCustomer)o);
+ }
+ }
try {
- getJasdlOntologyManager().loadOntology(c, URI.create("file://"+getCurrentDir()+"/onts/commerce.owl"), mappingStrategies);
- getJasdlOntologyManager().loadOntology(s, URI.create("file://"+getCurrentDir()+"/onts/society.owl"), mappingStrategies);
+ getJom().loadOntology(c, URI.create("file://"+getCurrentDir()+"/onts/commerce.owl"), mappingStrategies);
+ getJom().loadOntology(s, URI.create("file://"+getCurrentDir()+"/onts/society.owl"), mappingStrategies);
} catch (JASDLException e) {
e.printStackTrace();
@@ -69,9 +81,10 @@
updatePercepts();
+
}
-
+
private void updatePercepts(){
synchronized(model.getObjects()){
try{
@@ -116,7 +129,6 @@
@Override
public boolean executeAction(String agName, Structure action) {
Logger agentLogger = Logger.getLogger(agName);
-
try{
Term[] terms = new Term[action.getTerms().size()];
int i=0;
@@ -155,8 +167,18 @@
}
}
+ if(agent instanceof ModelCustomer){
+ ModelCustomer customer = (ModelCustomer)agent;
+ if(action.getFunctor().equals("request_product")){
+ customer.request(terms[0].toString(), terms[1].toString(), (int)((NumberTerm)terms[2]).solve());
+ }
+ if(action.getFunctor().equals("approve")){
+ return customer.approve(terms[0].toString());
+ }
+ }
+
}catch(ModelAgentException e){
agentLogger.info("Unable to complete action "+action+". Reason: ");
e.printStackTrace();
@@ -164,7 +186,7 @@
}finally{
updatePercepts();
}
- agentLogger.fine("Completed action "+action);
+ agentLogger.info("Completed action "+action);
return true;
}
Modified: trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/CommerceModel.java
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/CommerceModel.java 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/CommerceModel.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -51,7 +51,11 @@
shop1.addProductToCatalogue(new Product("bread", "kingsmill", 1.6, 750), 58);
shop1.addProductToCatalogue(new Product("milk", "cravendale", 0.9, 500), 33);
+ ModelShop shop2 = new ModelShop(new Atom("shop2"), new Point(5, 3), this, env);
+ shop2.addProductToCatalogue(new Product("beef", "farmer_jims_rump_steak", 1.4, 800), 22);
+
addObject(shop1);
+ addObject(shop2);
addObject(new ModelCustomer(new Atom("customer1"), new Point(10, 10), this, env));
addObject(new ModelCustomer(new Atom("customer2"), new Point(15, 8), this, env));
addObject(new ModelCustomer(new Atom("customer3"), new Point(19, 3), this, env));
@@ -60,6 +64,8 @@
addObject(new ModelPA(new Atom("pa1"), new Point(0, 0), this, env));
addObject(new ModelPA(new Atom("pa2"), new Point(0, 0), this, env));
+ updateObjects();
+
}
public void setView(CommerceView view){
Modified: trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelCustomer.java
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelCustomer.java 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelCustomer.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -13,9 +13,14 @@
import commerce.env.CommerceEnvironment;
public class ModelCustomer extends ModelMobileAgent {
+
+ private List<ModelCustomerListener> listeners;
+ private List<Request> requests;
public ModelCustomer(Atom id, Point position, CommerceModel model, CommerceEnvironment env) {
super(id, position, model, env);
+ requests = new Vector<Request>();
+ listeners = new Vector<ModelCustomerListener>();
}
public List<Literal> getPercepts() throws JASDLException{
@@ -37,6 +42,40 @@
return percepts;
}
+
+ public void addListener(ModelCustomerListener listener){
+ listeners.add(listener);
+ }
+
+ @Override
+ public void addPercepts() throws JASDLException {
+ super.addPercepts();
+ for(Request request : requests){
+ env.addPercept(getId().toString(), Literal.parseLiteral("ui_product_request("+request.productDescription+","+request.shopDescription+","+request.qty+")"));
+ }
+ requests.clear();
+ }
+
+
+ public void request(String productDescription, String shopDescription, int qty){
+ Request request = new Request(productDescription, shopDescription, qty);
+ System.out.println("Requested "+request);
+ requests.add(request);
+ }
+
+ /**
+ * Returns true if all listeners approve of this choice as a purchase
+ * @param brand
+ * @return
+ */
+ public boolean approve(String brand){
+ boolean result = true;
+ for(ModelCustomerListener listener : listeners){
+ result&=listener.approve(brand); // do all listeners approve of this choice?
+ }
+ return result;
+ }
+
protected float getOffset(){
return 0.6f;
}
@@ -45,4 +84,26 @@
return new Color(0, 100, 0);
}
+ /**
+ * Associates a product description with a quantity
+ * @author tom
+ *
+ */
+ class Request{
+ public String shopDescription;
+ public String productDescription;
+ public int qty;
+ public Request(String productDescription, String shopDescription, int qty) {
+ super();
+ this.shopDescription = shopDescription;
+ this.productDescription = productDescription;
+ this.qty = qty;
+ }
+
+ public String toString(){
+ return productDescription+" ("+qty+")";
+ }
+
+ }
+
}
Added: trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelCustomerListener.java
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelCustomerListener.java (rev 0)
+++ trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelCustomerListener.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -0,0 +1,17 @@
+package commerce.env.model;
+
+/**
+ * Classes interested in events from a ModelCustomer should implement this class and add themselves as a listener to ModelCustomer
+ * @author tom
+ *
+ */
+public interface ModelCustomerListener {
+
+ /**
+ * Listener implementations should return true iff they approve of this brand as a purchase.
+ * All listeners must approve for the choice to be accepted
+ * @param brand
+ * @return
+ */
+ public boolean approve(String brand);
+}
Modified: trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelShop.java
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelShop.java 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/env/model/ModelShop.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -9,7 +9,9 @@
import java.awt.Point;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+import java.util.Vector;
import commerce.env.CommerceEnvironment;
import commerce.exception.ModelShopException;
@@ -75,7 +77,10 @@
*/
@Override
public void addPercepts() throws JASDLException {
- super.addPercepts();
+ super.addPercepts();
+
+ List<Atom> differentIndividuals = new Vector<Atom>();
+
for(Product product : catalogue){
// add product
@@ -123,10 +128,22 @@
new NumberTermImpl(product.RRP),
new Term[0],
env.c)
- .getLiteral());
-
-
+ .getLiteral());
+
+ differentIndividuals.add(new Atom(product.brand));
}
+
+ // enter all products into an all_different assertion
+ Atom[] is = (Atom[]) differentIndividuals.toArray(new Atom[differentIndividuals.size()]);
+ env.addPercept(
+ getId().toString(),
+ env.getSELiteralFactory().construct(
+ true,
+ is,
+ new Atom[0],
+ env.c)
+ .getLiteral());
+
}
protected float getOffset(){
Added: trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/ui/customer/CustomerUIFrame.java
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/ui/customer/CustomerUIFrame.java (rev 0)
+++ trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/ui/customer/CustomerUIFrame.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -0,0 +1,36 @@
+package commerce.ui.customer;
+
+import java.awt.Dimension;
+
+import javax.swing.JFrame;
+import javax.swing.JTabbedPane;
+
+import commerce.env.CommerceEnvironment;
+import commerce.env.model.ModelCustomer;
+
+public class CustomerUIFrame extends JFrame{
+
+ private JTabbedPane tabs;
+ private CommerceEnvironment env;
+
+ public CustomerUIFrame(CommerceEnvironment env){
+ super("Commerce: Customer UI");
+ this.env = env;
+
+ setPreferredSize(new Dimension(220, 320));
+
+ tabs = new JTabbedPane();
+ add(tabs);
+ tabs.setVisible(true);
+
+ pack();
+ setVisible(true);
+ }
+
+ public void addCustomer(ModelCustomer customer){
+ CustomerUIPanel panel = new CustomerUIPanel(env, customer);
+ tabs.addTab(customer.getLabel(), panel);
+ }
+
+
+}
Added: trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/ui/customer/CustomerUIPanel.java
===================================================================
--- trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/ui/customer/CustomerUIPanel.java (rev 0)
+++ trunk/applications/jasdl-owlapi/examples/commerce/src/java/commerce/ui/customer/CustomerUIPanel.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -0,0 +1,88 @@
+package commerce.ui.customer;
+
+import jason.asSyntax.Literal;
+
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JSpinner;
+import javax.swing.JTextArea;
+import javax.swing.SpinnerNumberModel;
+
+import commerce.env.CommerceEnvironment;
+import commerce.env.model.ModelCustomer;
+import commerce.env.model.ModelCustomerListener;
+
+public class CustomerUIPanel extends JPanel implements ModelCustomerListener{
+ private JTextArea productDescriptionField;
+ private JButton submitButton;
+ private ModelCustomer customer;
+ private CommerceEnvironment env;
+ private JSpinner qty;
+ private JTextArea shopDescriptionField;
+
+ public CustomerUIPanel(CommerceEnvironment env, ModelCustomer customer){
+ super();
+ this.customer = customer;
+
+ customer.addListener(this);
+
+ this.env = env;
+ setupUI();
+ }
+
+ private void setupUI(){
+ JPanel productRequestPane = new JPanel();
+ add(productRequestPane);
+ productRequestPane.setPreferredSize(new Dimension(200, 200));
+ productRequestPane.setLayout(new BoxLayout(productRequestPane, BoxLayout.Y_AXIS));
+
+ productDescriptionField = new JTextArea(20, 8);
+ productRequestPane.add(productDescriptionField);
+
+ shopDescriptionField = new JTextArea(20, 8);
+ productRequestPane.add(shopDescriptionField);
+
+ JPanel buttonPane = new JPanel();
+ buttonPane.setPreferredSize(new Dimension(200, 100));
+ buttonPane.setLayout(new FlowLayout());
+ productRequestPane.add(buttonPane);
+
+ submitButton = new JButton("Submit");
+ buttonPane.add(submitButton);
+ submitButton.addActionListener(new ProductRequestSubmitButtonActionListener());
+
+ qty = new JSpinner(new SpinnerNumberModel(1, 0, 200, 1));
+ buttonPane.add(qty);
+
+ }
+
+ class ProductRequestSubmitButtonActionListener implements ActionListener{
+ public void actionPerformed(ActionEvent event) {
+ String productDescription = productDescriptionField.getText();
+ String shopDescription = shopDescriptionField.getText();
+
+ // strip new lines
+ productDescription = productDescription.replace("\n", " ");
+ shopDescription = shopDescription.replace("\n", " ");
+ env.executeAction(customer.getId().toString(), Literal.parseLiteral(
+ "request_product(\""+productDescription+"\","+"\""+shopDescription+"\","+qty.getValue()+")"));
+ }
+ }
+
+ public boolean approve(String brand) {
+ int n = JOptionPane.showConfirmDialog(
+ this,
+ "Does the following product meet your requirements?\n"+brand,
+ "Your personal agent seeks your approval",
+ JOptionPane.YES_NO_OPTION);
+
+ return n == JOptionPane.YES_OPTION;
+ }
+}
Modified: trunk/applications/jasdl-owlapi/src/jasdl/JASDLParams.java
===================================================================
--- trunk/applications/jasdl-owlapi/src/jasdl/JASDLParams.java 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/src/jasdl/JASDLParams.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -10,6 +10,10 @@
import jason.asSyntax.Atom;
public class JASDLParams {
+ public static String JASDL_TG_CAUSE_RETAIN_ANNOTS = "JASDL_TG_CAUSE_RETAIN_ANNOTS";
+
+ public static String JASDL_TG_CAUSE = "JASDL_TG_CAUSE";
+
/**
* Functor of the structure containing the ontology label which maps to the ontology a SE-Literal refers to
*/
Modified: trunk/applications/jasdl-owlapi/src/jasdl/architecture/JASDLAgArch.java
===================================================================
--- trunk/applications/jasdl-owlapi/src/jasdl/architecture/JASDLAgArch.java 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/src/jasdl/architecture/JASDLAgArch.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -47,7 +47,7 @@
public void initAg(String agClass, ClassParameters bbPars, String asSrc, Settings stts) throws JasonException {
super.initAg(agClass, bbPars, asSrc, stts);
- processor = new ProtocolProcessor(getAgent().getJom(), getAgent().getDefaultMappingStrategies(), getAgent().getSELiteralFactory());
+ processor = new ProtocolProcessor(getAgent().getJom(), getAgent().getDefaultMappingStrategies());
}
@Override
Modified: trunk/applications/jasdl-owlapi/src/jasdl/asSemantics/JASDLAgent.java
===================================================================
--- trunk/applications/jasdl-owlapi/src/jasdl/asSemantics/JASDLAgent.java 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/src/jasdl/asSemantics/JASDLAgent.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -22,6 +22,7 @@
import jasdl.JASDLParams;
import jasdl.asSyntax.JASDLPlanLibrary;
+import jasdl.asSyntax.SEPlan;
import jasdl.bb.JASDLBeliefBase;
import jasdl.bb.bebops.JASDLIncisionFunction;
import jasdl.bb.bebops.JASDLKernelsetFilter;
@@ -35,7 +36,6 @@
import jasdl.bridge.mapping.label.LabelManager;
import jasdl.bridge.mapping.label.OntologyURIManager;
import jasdl.bridge.seliteral.SELiteral;
-import jasdl.util.exception.JASDLConfigurationException;
import jasdl.util.exception.JASDLException;
import jasdl.util.exception.JASDLNotEnrichedException;
import jason.JasonException;
@@ -61,7 +61,6 @@
import org.semanticweb.owl.model.OWLAxiom;
import org.semanticweb.owl.model.OWLDataFactory;
import org.semanticweb.owl.model.OWLDescription;
-import org.semanticweb.owl.model.OWLIndividualAxiom;
import org.semanticweb.owl.model.OWLOntology;
import org.semanticweb.owl.model.OWLOntologyManager;
import org.semanticweb.owl.model.RemoveAxiom;
@@ -88,11 +87,8 @@
private JASDLOntologyManager jom;
- private SELiteralFactory seLiteralFactory;
- public AxiomToSELiteralConverter axiomToSELiteralConverter;
- private SELiteralToAxiomConverter SELiteralToAxiomConverter;
private JASDLAgentConfigurator config;
@@ -102,12 +98,12 @@
// instantiate utility classes
jom = new JASDLOntologyManager(getLogger());
config = new JASDLAgentConfigurator(this);
- seLiteralFactory = new SELiteralFactory(getJom());
- SELiteralToAxiomConverter = new SELiteralToAxiomConverter(this);
- axiomToSELiteralConverter = new AxiomToSELiteralConverter(this);
+
// override plan library
setPL(new JASDLPlanLibrary(this));
+
+
}
@@ -122,7 +118,12 @@
config.preInitConfigure(stts);
TransitionSystem ts = super.initAg(arch, bb, src, stts);
config.postInitConfigure(stts);
+
+ for(SEPlan se : ((JASDLPlanLibrary)getPL()).getSEPlans()){
+ getLogger().finest(se.getTrigger().toString());
+ }
+
return ts;
}
@@ -275,6 +276,10 @@
return getTS().getUserAgArch().getAgName();
}
+ public SELiteralFactory getSELiteralFactory(){
+ return getJom().getSELiteralFactory();
+ }
+
public List<MappingStrategy> getDefaultMappingStrategies() {
return config.getDefaultMappingStrategies();
}
@@ -307,16 +312,12 @@
return getJom().getReasoner();
}
- public SELiteralFactory getSELiteralFactory() {
- return seLiteralFactory;
- }
-
public SELiteralToAxiomConverter getSELiteralToAxiomConverter() {
- return SELiteralToAxiomConverter;
+ return getJom().getSELiteralToAxiomConverter();
}
public AxiomToSELiteralConverter getAxiomToSELiteralConverter() {
- return axiomToSELiteralConverter;
+ return getJom().getAxiomToSELiteralConverter();
}
public OWLDataFactory getOWLDataFactory() {
Modified: trunk/applications/jasdl-owlapi/src/jasdl/asSemantics/JASDLAgentConfigurator.java
===================================================================
--- trunk/applications/jasdl-owlapi/src/jasdl/asSemantics/JASDLAgentConfigurator.java 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/src/jasdl/asSemantics/JASDLAgentConfigurator.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -19,8 +19,8 @@
*/
package jasdl.asSemantics;
-import static jasdl.util.Common.getCurrentDir;
-import static jasdl.util.Common.strip;
+import static jasdl.util.JASDLCommon.getCurrentDir;
+import static jasdl.util.JASDLCommon.strip;
import jasdl.JASDLParams;
import jasdl.bridge.factory.AliasFactory;
import jasdl.bridge.mapping.aliasing.Alias;
@@ -52,8 +52,6 @@
private HashMap<Atom, Float> trustMap;
private boolean beliefRevisionEnabled;
-
- private boolean annotationGatheringEnabled;
private boolean contractionEnabled;
@@ -200,7 +198,7 @@
}
public void setAnnotationGatheringEnabled(boolean b) {
- this.annotationGatheringEnabled = b;
+ agent.getJom().setAnnotationGatheringEnabled(b);
}
/**
@@ -364,7 +362,7 @@
}
public boolean isAnnotationGatheringEnabled() {
- return annotationGatheringEnabled;
+ return agent.getJom().isAnnotationGatheringEnabled();
}
public boolean isBeliefRevisionEnabled() {
Modified: trunk/applications/jasdl-owlapi/src/jasdl/asSyntax/JASDLPlanLibrary.java
===================================================================
--- trunk/applications/jasdl-owlapi/src/jasdl/asSyntax/JASDLPlanLibrary.java 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/src/jasdl/asSyntax/JASDLPlanLibrary.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -21,24 +21,31 @@
import jasdl.asSemantics.JASDLAgent;
import jasdl.bridge.seliteral.SELiteral;
+import jasdl.util.JASDLCommon;
import jasdl.util.exception.JASDLException;
+import jasdl.util.exception.JASDLInvalidSELiteralException;
import jasdl.util.exception.JASDLNotEnrichedException;
import jason.JasonException;
import jason.asSyntax.Literal;
import jason.asSyntax.Plan;
import jason.asSyntax.PlanLibrary;
+import jason.asSyntax.Structure;
import jason.asSyntax.Term;
import jason.asSyntax.Trigger;
-import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
-import java.util.Set;
import java.util.Vector;
import java.util.logging.Logger;
+import org.semanticweb.owl.model.OWLException;
+
/**
- * TODO: What about lists with nested SE-Literals? Prohibit?
- * @author tom
+ *
+ * SE-Plans are ordered most specific -> most general, ensuring the most specific option is generalised to.
+ * TODO: write tests
+ *
+ * @author Tom Klapiscak
*
*/
public class JASDLPlanLibrary extends PlanLibrary {
@@ -48,24 +55,113 @@
/**
* Keep track of SE Plans for generating candidate relevances for incoming triggers containing SE-Literals
*/
- private Set<SEPlan> sePlans;
+ private LinkedList<SEPlan> sePlans;
public JASDLPlanLibrary(JASDLAgent agent) {
this.agent = agent;
- sePlans = new HashSet<SEPlan>();
+ sePlans = new LinkedList<SEPlan>();
}
+
@Override
public void add(Plan p) throws JasonException {
// All plan who's trigger contains a SE-Literal is added as an SE-Plan so DL-unification can be performed when checking its relevance
if (containsSELiteral(p.getTrigger().getLiteral())) {
SEPlan sePlan = new SEPlan(agent, p);
- sePlans.add(sePlan);
+
+ try {
+ insertSEPlan(sePlan);
+ } catch (OWLException e) {
+ throw new JasonException("Error placing SE-Plan "+p, e);
+ }
+
super.add(sePlan);
} else {
super.add(p);
}
}
+
+ /**
+ * Inserts an SE-Plan according to its specificity (most specific first).
+ * TODO: Is this not better placed within a JMCA option selection strategy?
+ */
+ private void insertSEPlan(SEPlan unplaced) throws JASDLException, OWLException{
+ int i = 0;
+ for(SEPlan placed : sePlans){
+ Literal x = unplaced.getTrigger().getLiteral();
+ Literal y = placed.getTrigger().getLiteral();
+ boolean xIsMoreSpecific = isMoreSpecific(x, y);
+ getLogger().finest("Is "+x+" more specific than "+y+"? "+xIsMoreSpecific);
+ if(xIsMoreSpecific) break;
+ i++;
+ }
+ sePlans.add(i, unplaced);
+ }
+
+
+ public List<SEPlan> getSEPlans(){
+ return sePlans;
+ }
+
+ /**
+ * Semantically naive literals are always considered more specific than semantically enriched.
+ * Do not need to consider incomparable literals (those with different arities or those with different semantic enrichment state)
+ * since one can never generalise to the other.
+ *
+ * Algorithm functions as follows:
+ *
+ * Terminal cases:
+ * if either x or y is not a structure, they are incomparable (different arities (at least one has no terms))
+ * If arity(x)!=arity(y) then they are considered incomparable and we (arbitrarily) return arity(x)<arity(y)
+ * If SN(x) and SE(y) then we return true
+ * if SE(x) and SN(y) then we return false
+ * if SE(x) and SE(y) then we return subsumes(y, x) (i.e. true if x is more specific)
+ *
+ * Recursive case:
+ * score=0
+ * if SN(x) and SN(y) then
+ * for each term of x and y in parallel
+ * if isMoreSpecific(x, y) then score++ else score--
+ *
+ * if score>=0 then we return true (i.e. x has a greater number of more specific terms than y) else false
+ *
+ */
+ private boolean isMoreSpecific(Term _x, Term _y) throws JASDLException, OWLException{
+ if(!_x.isStructure() || !_y.isStructure()) return false;
+ Structure x = (Structure)_x;
+ Structure y = (Structure)_y;
+
+ if(x.getArity() != y.getArity()) return false;
+ SELiteral sx = null;
+ SELiteral sy = null;
+
+ try {
+ if(x.isLiteral()) sx = agent.getSELiteralFactory().construct((Literal)x);
+ } catch (JASDLInvalidSELiteralException e) {
+ }
+
+ try {
+ if(y.isLiteral()) sy = agent.getSELiteralFactory().construct((Literal)y);
+ } catch (JASDLInvalidSELiteralException e) {
+ }
+
+ if((sx == null && sy != null) || (sx != null && sy == null)) return false;
+
+ if(sx != null && sy != null) return JASDLCommon.subsumes(agent.getJom(), sy.toOWLObject(), sx.toOWLObject());
+
+ // both sx and sy are semantically-naive and have equivalent arities
+ int score = 0;
+ for(int i=0; i<x.getArity(); i++){
+ Term xt = x.getTerm(i);
+ Term yt = y.getTerm(i);
+
+ if(isMoreSpecific(xt, yt)) score++; else score--;
+
+ }
+
+ if(score>=0) return true; else return false;
+ }
+
@Override
public List<Plan> getCandidatePlans(Trigger te) {
@@ -77,6 +173,8 @@
candidates = new Vector<Plan>();
}
candidates.addAll(sePlans);
+
+
}
return candidates;
Modified: trunk/applications/jasdl-owlapi/src/jasdl/asSyntax/SEPlan.java
===================================================================
--- trunk/applications/jasdl-owlapi/src/jasdl/asSyntax/SEPlan.java 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/src/jasdl/asSyntax/SEPlan.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -19,11 +19,15 @@
*/
package jasdl.asSyntax;
+import jasdl.JASDLParams;
import jasdl.asSemantics.JASDLAgent;
+import jasdl.bridge.DLUnifier;
import jason.asSemantics.Unifier;
+import jason.asSyntax.Literal;
import jason.asSyntax.Plan;
+import jason.asSyntax.Term;
import jason.asSyntax.Trigger;
-import jasdl.bridge.DLUnifier;
+import jason.asSyntax.VarTerm;
/**
* <p>A plan whose trigger is associated with a semantically-enriched literal.</p>
@@ -32,7 +36,7 @@
* @author Tom Klapiscak
*
*/
-public class SEPlan extends Plan {
+public class SEPlan extends Plan{
private static final long serialVersionUID = 1L;
private JASDLAgent agent;
@@ -44,12 +48,23 @@
@Override
public Unifier isRelevant(Trigger te) {
- Unifier un = super.isRelevant(te); // better solution? extend unifier?
+ Unifier un = super.isRelevant(te);
if (un != null) { // plan is specifically relevant to deal with the trigger
return un;
}
DLUnifier dlun = new DLUnifier(agent);
if (dlun.unifiesNoUndo(getTrigger(), te)) { // <- plan's trigger subsumes incoming
+
+ Literal causeWithAnnots = (Literal)te.getLiteral().clone();
+ dlun.unifiesNoUndo(new VarTerm(JASDLParams.JASDL_TG_CAUSE_RETAIN_ANNOTS), causeWithAnnots);
+
+ Literal causeNoAnnots = (Literal)te.getLiteral().clone();
+ Term o = causeNoAnnots.getAnnots(JASDLParams.ONTOLOGY_ANNOTATION_FUNCTOR).get(0);
+ causeNoAnnots.clearAnnots();
+ causeNoAnnots.addAnnot(o);
+ dlun.unifiesNoUndo(new VarTerm(JASDLParams.JASDL_TG_CAUSE), causeNoAnnots);
+
+
return dlun;
} else {
return null;
Modified: trunk/applications/jasdl-owlapi/src/jasdl/bb/JASDLBeliefBase.java
===================================================================
--- trunk/applications/jasdl-owlapi/src/jasdl/bb/JASDLBeliefBase.java 2008-04-18 18:55:08 UTC (rev 1229)
+++ trunk/applications/jasdl-owlapi/src/jasdl/bb/JASDLBeliefBase.java 2008-04-20 16:47:30 UTC (rev 1230)
@@ -146,7 +146,7 @@
BeliefBaseContractor contractor = new BeliefBaseContractor(agent.getOntologyManager(), new JASDLReasonerFactory(), agent.getLogger());
removeList = contractor.contract(axiom, new JASDLKernelsetFil...
[truncated message content] |