Giter Site home page Giter Site logo

jill's Introduction

Jill

Codacy Badge Codacy Badge main dev

About

Jill is an open source initiative to deliver a fast and lightweight java-based BDI-like (Beliefs, Desires, Intentions) execution engine for developing large-scale multi-agent systems. Jill is:

  • A BDI execution engine: that supports complex BDI goal-plan behaviour hierarchies in the PRS style (A Rao and M Georgeff. BDI Agents: from theory to practice. In ICMAS, volume 95, pages 312โ€“319, 1995).

  • Lightweight: the design and implementation is heavily optimised to deliver a very lightweight distribution (see Releases for details) fit for inclusion in web-based and embedded-Java applications.

  • Fast: The Jill BDI execution engine is very fast, and was designed from ground-up to handle millions of BDI agents (see Benchmarks and Examples).

  • Java-based: The programming of BDI agents in Jill is done in pure Java, so users benefit from the various support tools that are available to Java developers, such as full integration with the Eclipse IDE. Jill itself is written in Java and is distributed as a JAR bundle which can be easily integrated into larger projects that require cognitive reasoning agents.

  • Open source: Jill is released under the terms of the GNU General Lesser Public License http://www.gnu.org/licenses/lgpl-3.0.html.

Releases

The latest stable release as well as all previous releases are available at https://github.com/agentsoz/jill/releases.

Usage

Jill is available from Maven Central. To include in your project add the following maven dependency to your pom.xml:

<dependencies>
    ...
    <dependency>
        <groupId>io.github.agentsoz</groupId>
        <artifactId>jill</artifactId>
        <version>0.4.0</version>
    </dependency>
    ...
</dependencies>

Or it can be built locally using the supplied maven wrapper:

./mvnw clean package

Benchmarks and Examples

The following tests were run on a 2022 Macbook Pro (18,3 model) laptop with Apple M1 Max Pro chip with 8-core CPU, SSD, 32GB RAM, with maximum memory available to tests (JVM heap size) set to 12GB.

1. The Towers of Hanoi

A solution for the classic towers of hanoi puzzle is available in the examples directory (see hanoi player). The goal is to move a stack of discs from the Pin0 (the first pin) to Pin3 (the third pin).

The hanoi player can be run using the convinience script test/hanoi.sh:

> ./test/hanoi.sh
...
[main] INFO io.github.agentsoz.jill - Finished loading 1 agents
[main] INFO io.github.agentsoz.jill - Created 1 agents in (12 ms)
[main] INFO io.github.agentsoz.jill - Started 1 agents in (2 ms)
[main] INFO io.github.agentsoz.jill - Finished running 1 agents in (2181 ms)
[main] INFO io.github.agentsoz.jill - Terminated 1 agents in (1 ms)
...
Solved Towers of Hanoi with 20 discs in 1048575 moves

The log output gives some idea of performance in terms of the number of moves and time taken to complete the puzzle. The output of the run, i.e., the solution, is written to ./test/hanoi.out:

> head -4 ./test/hanoi.out
Initialised hanoi board with 20 discs:
|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1
|
|

> tail -20 test/hanoi.out
Moving disc 1 from pin 2 to 0
|2|1
|3
|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4
Moving disc 3 from pin 1 to 2
|2|1
|
|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3
Moving disc 1 from pin 0 to 1
|2
|1
|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3
Moving disc 2 from pin 0 to 2
|
|1
|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2
Moving disc 1 from pin 1 to 2
|
|
|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1

2. 10 Million BDI Agents

This test executes 10 million relatively complex BDI agents (see TestAgent.java). Each agent has a goal-plan hierarchy as follows:

            GoalA
        .-----^-----.
      PlanA       PlanD
    .---^---.
  GoalB   GoalC
    |       |
  PlanB   PlanC

Each agent starts by posting a high level goal GoalA which has two relevant plans PlanA and PlanD. In this example the context condition of all plans is true so that all relevant plans are also applicable at the same time. So given that PlanA and PlanD are both applicable, which should get selected? That depends on the global plan selection policy configured for Jill. By default it selects a plan instance at RANDOM, but this can be changed to always pick the first defined plan (command line option --plan-selection-policy FIRST) or last (option --plan-selection-policy LAST).

If PlanD were selected, it executes (always successfully), after which GoalA is satisfied, and the agent becomes idle. On the other hand, if PlanB was selected, it then first posts GoalB--and waits for it to complete--followed by GoalC. This results in PlanB executing and completing first, followed by PlanC. At that point all steps (i.e., subgoals GoalB and GoalC) of PlanA have completed, which in turn results in its completion and the success of the top level goal GoalA.

Note that the execution of the agents is interleaved such that Jill cycles through all agents in each execution cycle, and progresses any active intentions (plans) by one plan step. When all agents eventually accomplish their GoalA and become idle, the program terminates (this behaviour can be disabled by passing the Jill option --exit-on-idle FALSE at runtime).

To execute the test with 10 million BDI agents, use the convinience script test/testagent.sh as follows:

> ./test/testagent.sh
...
[main] INFO io.github.agentsoz.jill - Created 10000000 agents in (1486 ms)
[main] INFO io.github.agentsoz.jill - Started 10000000 agents in (1926 ms)
[main] INFO io.github.agentsoz.jill - Finished running 10000000 agents in (8528 ms)
[main] INFO io.github.agentsoz.jill - Terminated 10000000 agents in (84 ms)

That took ~8.5 seconds to run 10 million BDI agents to completion, not bad!

3. Hello Neighbour

This example case is that of an agent (Greeter.java), who has several neighbours and--feeling rather jovial this bright day--wishes to greet one of them. No one in particular mind you, just someone who is a male. Indeed, there must have been something in the air, because all agents in the example feel exactly the same way.

This crafted scenario is perfect for highlighting the use of binding variables in context conditions of plans. Basically what we want is to be able to specify the condition (select a male neighbour) in the context condition, and let Jill give us a binding (such as "Oscar N. Morton") who we can say hello to. (In fact Jill will create one plan instance for each match and which one of those will actually be selected for execution will depend on the --plan-selection-policy setting). The function GreetNeighbour::context() shows how to specify such a context condition. Internally, this executes as a query on the belief database of the agent and returns one plan instance for each match (in this case one plan instance per male neighbour). Inside the plan, the match must then be bound to a plan variable so that it can be used inside the plan body. This is done in GreetNeighbour::setPlanVariables(Map<String, Object> vars) where the matched neighbours name is saved in a plan variable. (Here vars is a list of key-value pairs--the belief database table column names being the keys, and the matched record being the values.) The saved name is then used inside the plan body to say hello to that neighbour.

The script ./test/greeter.sh runs this example in various configurations changing the number of agents and the number of neighbours per agent:

> ./test/greeter.sh

Running 10000 agents with 10 neighbours each (see greeter-10000a-10b.*)
...
[main] INFO io.github.agentsoz.jill - Created 10000 agents in (30 ms)
[main] INFO io.github.agentsoz.jill - Started 10000 agents in (61 ms)
[main] INFO io.github.agentsoz.jill - Finished running 10000 agents in (85 ms)
[main] INFO io.github.agentsoz.jill - Terminated 10000 agents in (2 ms)
...
Running 50000 agents with 50 neighbours each (see greeter-50000a-50b.*)
...
[main] INFO io.github.agentsoz.jill - Created 50000 agents in (81 ms)
[main] INFO io.github.agentsoz.jill - Started 50000 agents in (549 ms)
[main] INFO io.github.agentsoz.jill - Finished running 50000 agents in (245 ms)
[main] INFO io.github.agentsoz.jill - Terminated 50000 agents in (9 ms)
...
Running 100000 agents with 100 neighbours each (see greeter-100000a-100b.*)
...
[main] INFO io.github.agentsoz.jill - Created 100000 agents in (85 ms)
[main] INFO io.github.agentsoz.jill - Started 100000 agents in (1934 ms)
[main] INFO io.github.agentsoz.jill - Finished running 100000 agents in (394 ms)
[main] INFO io.github.agentsoz.jill - Terminated 100000 agents in (20 ms)
...

4. Token Passing

In this setup a group of agents (TokenAgent2.java) are connected together in a ring configuration such that each agent can talk to two others, one on either side. The benchmark simply passes a token around in the ring, varying the number of agents and rounds for which the token is passed. The output snippet below is for 10,000 agents passing the token for 100 rounds:

> ./test/tokenpassing.sh
...
Running token passing version 2 between 10000 agents for 100 rounds (see tokenpassing2-10000a-100r.*)
...
[main] INFO io.github.agentsoz.jill - Finished loading 10000 agents
[main] INFO io.github.agentsoz.jill - Created 10000 agents in (31 ms)
[main] INFO io.github.agentsoz.jill - Started 10000 agents in (4 ms)
[main] INFO io.github.agentsoz.jill - Finished running 10000 agents in (1564 ms)
[main] INFO io.github.agentsoz.jill - Terminated 10000 agents in (1 ms)

Developers

Jill uses Apache Maven (http://maven.apache.org) to manage the build process and the entire software life cycle.

License

Jill Cognitive Agents Project Copyright (c) 2014 - 2023, by its authors. See AUTHORS file.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Contact

Dhirendra Singh <[email protected]>

jill's People

Contributors

dependabot[bot] avatar dhixsingh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

jill's Issues

How does jill choose "PlanVariables"

Hi,

I am trying to work with jill, I had a question, how is selecting a plan relate to selecting variables to that plan,

Consider I have 2 plans to go to park
Walk and Taxi
and I have 5 parks, So the function for a random selection (Or first,last), the algorithm should choose 1- a plan by random and 2- a tuple from its bindings randomly. Is this function really doing this?

private Plan selectPlanAtRandom() {
        Plan plan = null;
        Set<Belief> vars = null;
        int index = rand.nextInt(size());
        int idx = 0;
        boolean bindingsExist = false;
        for (Plan p : bindings.keySet()) {
            vars = bindings.get(p);
            bindingsExist = (vars != null && !vars.isEmpty());
            idx += bindingsExist ? vars.size() : 1;
            if (idx > index) {
                plan = p;
                if (bindingsExist) {
                    index = index - (idx - vars.size());
                    setPlanVariables(plan.getAgent(), plan, vars, index);
                }
                break;
            }
        }
        return plan;
    }

I think the relation between Plans index and Bindings index is lost here.

Thanks

Event system/Reactive bahavior/Plan failure

Hi,

Does Jill have these features at this point? If not, Do you plan to add them?

1- Events and Reactive behavior of agents,new beliefs that can fire new goals or plans.
2- Plan failure recovery and back propagation.

Thanks

Add support for multiple intention stacks

Jill agents currently have a single intention stack

private final Stack255 executionStack;

which means that only one top level goal can be progressed at a time. All other goals will be subgoals that are pushed on to the same stack leading to the current intention being suspended until the pushed goal is completed.

We want the ability to have several intention stacks such that more than one intention is active at any time and all active intentions are progressed together (per cycle, one plan step should be progressed per intention stack, where the stack is selected using round robin).

Implement BDI plan step failure

What is required is the ability to allow plan steps to fail. BDI plans are currently described by a sequence of plan steps as below:

PlanStep[] steps = {new PlanStep() {
public void step() {
((TestAgent) getAgent()).setStatus(((TestAgent) getAgent()).getStatus() | 0x0001);
}
}, new PlanStep() {
public void step() {
post(new GoalB("gB"));
}
}, new PlanStep() {
public void step() {
post(new GoalC("gC"));
}
},};

The solution is to update the following step() function to instead return a boolean to indicate if the step (which could be an atomic action in the environment, or a sub-goal) has failed:

Then the intention selction machinery should to be updated to handle cases where a plan step returns false. If it does, then the plan must be aborted ie no further steps should be executed, and the plan itself should be failed (no mechanism to indicate plan failure exists yet either). The relevant code for this is here:

} else {
logger.debug(Log.logPrefix(agentIndex) + " is executing a step of plan "
+ node.getClass().getSimpleName());
node.step();
}

Initialising more than two agent types fails

The following test will fail if more then two agent types were initialised:

public void testInitialisingMultipleAgentTypes() {
final String output = "a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 "
+ "a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 "
+ "a20 a21 a22 a23 a24 a25 a26 a27 a28 a29 "
+ "a30 a31 a32 a33 a34 a35 a36 a37 a38 a39 "
+ "a40 a41 a42 a43 a44 a45 a46 a47 a48 a49 "
+ "777777777777777777777777777777";
final String[] args = {"--plan-selection-policy", "FIRST",
"--config", "{"
+ "randomSeed:123456,"
+ "numThreads:1,"
+ "agents:["
+ "{classname:io.github.agentsoz.jill.testprogram.LogAgent, args:[\"-d\"], count:50},"
+ "{classname:io.github.agentsoz.jill.testprogram.TestAgent,args:[\"-d\"], count:30}"
+ "]"
+ "}"};
Main.main(args);
assertEquals(output, out.toString());
}
}

For instance, the Jill engine crashes if the input is changed as follows:

        + "{classname:io.github.agentsoz.jill.testprogram.LogAgent, args:[\"-d\"], count:50},"
        + "{classname:io.github.agentsoz.jill.testprogram.TestAgent,args:[\"-d\"], count:30},"
        + "{classname:io.github.agentsoz.jill.testprogram.LogAgent,args:[\"-d\"], count:5},"
        + "{classname:io.github.agentsoz.jill.testprogram.TestAgent,args:[\"-d\"], count:5}"

The bug is in the logic in this line:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.