What you’ll build

The aim is to program an agent able to act in a dynamic environment in accordance with a plan achieving its goal. You will program this agent, situated in a simple environment that it is able to perceive and to act on.

What you’ll need

Code

You can download the solutions to the last question from here.

1. Problem description

The planning domain that we are considering concerns the (strongly simplified) domain of building an house.

1.1. Context description

Predicates are used to describe states and goals of this domain. In the following the number suffixing a predicate corresponds to the arity of the predicate, i.e. number of parameters. The parameter is in italic in the description of the predicate (e.g. house is the parameter of field_bought). The predicates are as follows:

  • field_bought/1: the site where the house has to be built has been bought by the owner.

  • site_prepared/1: the site where the house has to be build is ready. The building of the house can start.

  • floors_laid/1: the floors of the house have been laid.

  • roofs_built/1: the roofs of the house have been built.

  • walls_built/1: the walls of the house have been built.

  • windows_fitted/1: the windows of the house have been fitted in the walls.

  • doors_fitted/1: the doors of the house have been fitted in the walls.

  • electrical_system_installed/1: the electrical system of the house has been installed.

  • plumbing_installed/1: the plumbing of the house has been done.

  • exterior_painted/1: the painting outside of the house has been done.

  • interior_painted/1: the painting inside the house has been done.

  • house_built/1: the house has been built and is ready to be inhabited.

1.2. Operations description

Placing ourselves at a certain level of abstraction, the operations that the agent can use are:

  1. prepare_site/1 is possible when the field has been bought (field_bought). It achieves the state site_prepared

  2. lay_floors/1 is possible when the site is prepared (site_prepared) and achieves floors_laid

  3. build_walls/1 is possible when the floors have ben laid (floors_laid) and achieves the state walls_built

  4. build_roofs/1 is possible when the walls have been built (walls_built) and achieves the state roofs_built

  5. fit_windows/1 is possible when the walls have been built (walls_built) and achieves the state windows_fitted

  6. fit_doors/1 is possible when the walls have been built (walls_built) and achieves the state doors_fitted

  7. install_electrical_system/1 is possible when the roofs have built (roofs_built), the windows (windows_fitted) and doors (doors_fitted) have been fitted. It achieves the state electrical_system_installed

  8. install_plumbing/1 is possible when the roofs have been built (roofs_built), the windows (windows_fitted) and doors (doors_fitted) have been fitted. It achieves the state plumbing_installed

  9. paint_exterior/1 is possible when the roofs have been built (roofs_built), the windows (windows_fitted) and doors have been fitted (doors_fitted). It achieves the state exterior_painted

  10. paint_interior/1 is possible when the plumbing has been done (plumbing_installed), the electrical system has been installed (electrical_system_installed) and the exterior has been painted (exterior_painted). It achieves the state house_built

1.3. Plan for building an house

From the modeling of the domain (predicates and operations), different non linear or linear plans can be computed. For instance, one of this plan is (";" for sequence operator and "|" for parallel operator):

a ; b ; c ; (d | e | f) ; (g | h | i) ; j

2. Living in the best of the possible worlds

Now that we have a plan proposing a set of operations applicable from the initial state to achieve the goal state, let’s turn to its programming in an agent. The operations that are considered in the plan in the previous sections are programmed as sub-goals in a Jason Plan. The parameter introduced in their modeling corresponds to the house name.

  • Download and extract the following code, open the folder.

  • In eclipse, create a jacamo project build_house

  • In this project, copy and paste in the src/env folder the code coming from the src/env folder (should be package simulator), in the project folder, copy the file build_house.jcm

2.1. Version 1

  • Create an agent type companyv1.asl in the folder src/agt.

  • Open the build_house.jcm file and modify it so that you can execute this type of agent from the .jcm file

  • In the agent file, write a Jason plan corresponding to a plan for building an house: sequence of sub-goal creations corresponding each to a defined operation in previous section

  • For each of the sub-goals appearing in this plan, write a new Jason plan for achieving each of them. Such Jason plan corresponds to the operation model that has been defined above.
    In the body of such Jason plan, we use the corresponding action which is provided by the artifact of type House created in the environment.
    House is an /artifact/ (java class defined in the Cartago framework) offering the following set of actions to an agent: prepareSite, layFloors, buildWalls, buildRoof, fitWindows, fitDoors, installElectricalSystem, installPlumbing, paintExterior, paintInterior.

    Each of the actions generates the belief state corresponding to its result when executed with success (e.g. site_prepared for action prepareSite)

  • When all these plans have been defined, add to the agent a Jason plan triggered by the creation of the belief field_bought/1:

+field_bought(H) <- !lookForHouse(H); !!house_built(H).

@look_for_house_p2 // name of the plan
+!lookForHouse(H) : true <- lookupArtifact(H,ArtId);
    +house(H,ArtId).

@look_for_house_failure
-!lookForHouse(H) : true <- .print("Problem in the management of house ",H).

{ include("$jacamoJar/templates/common-cartago.asl") }
  • Execute the program. The result should be the following.

image

2.2. Version 2

  • Make a new version of companyv1.asl to companyv2.asl.

  • Adapt the build_house.jcm file so that you can execute this new version of the agent.

  • Change the global plan so that the agent could execute some of the goals in parallel as the modeling of the operations permits it.

  • Execute the agent

3. Living in a more realistic world

In the previous execution of the agent, every operation executed as if it was in an "ideal world" where all the resources are available and all the actions can execute. However this is not exactly the case in real world situations.

  • For instance, let’s consider that the site cannot be prepared if the weather is not fine (belief weather(fine)). How could we change the definition of the plan aiming at realizing the operation prepare_site.

  • Make a new version of companyv2.asl to companyv3.asl. Adapt the build_house.jcm file so that you can execute this new version of the agent.

  • Modify the agent code to handle the weather not fine for site preparation

  • Using the definition of contingency plans, add plans to handle such a situation by blocking the execution of the plan till the belief weather(fine) becomes true (to that aim, you can use the Jason internal action .wait(aPredicate)).

  • Test this new version of the agent

  • Note: In order to make the agent believes that the weather is fine, you can create an agent (using REPL command) alice sending it a message telling it that the weather is fine.

With this example, we clearly see how the agent executing a predefined plan is able to adapt its execution according to the current context of execution.

4. Living in a world where resources are distributed

  • Make a new version of companyv3.asl to companyv4.asl.

  • Adapt the build_house.jcm file so that you can execute this new version of the agent.

  • Using the same method, modify and adapt the corresponding plans conditioning the achievement of build_roofs and build_walls to the availability of woods and concrete respectively in the stock (beliefs stock(wood), stock(concrete)).

  • Checking of availability of woods or concrete in your company may be done using a question goal.

  • In order to renew its stock the agent will send a message to the agent wood_concrete_seller. To make it simple (you can make it more complex if you wish so), the wood_concrete_seller agent just sends a message telling that stock(concrete) and stock(woods) have been renewed, and this each time an agent requests for it.

  • Let’s remind that sending a message can be realized with the Jason internal action .send (see the slides for the different types of messages that can be sent).

  • Use the verbs corresponding to the type of behaviour that the wood_concrete_seller executes when receiving the message.

/* Initial beliefs and rules */

last_order_id(wood,1). // initial belief
last_order_id(concrete,1). // initial belief

/* Plans */

+!deliver(Product)[source(Ag)] : last_order_id(Product,N)
  <- -last_order_id(Product,_);
     +last_order_id(Product,N+1);
     .print("delivering ",Product, " to ", Ag);
     .send(Ag, tell, delivered(Product)).
  • Make a generic behaviour (Jason plan) so that when the company receives a message from the seller, it updates the stock with the corresponding product.

  • Reopen the archive and copy the code of wood_concrete_seller.asl agent in src/agt. Uncomment in the build_house.jcm file the part corresponding to the execution of this agent.

  • Test and execute it.

5. Further steps

  • Introduce several agents built on the same file and building each a different house

  • Instead of using the belief produced by the artifact to check the preconditions of the operations use the beliefs produced by another agent who is validating the good execution. + introduce a new agent who monitors the execution getting the beliefs from the environment and validates them by sending to the company agent a corresponding belief (you will have to use annotation of belief to check the source of the belief.) + The solution can downloaded from here