Skip to content

Commit

Permalink
move relevant/applicable plan methods from TS to Agent
Browse files Browse the repository at this point in the history
  • Loading branch information
jomifred committed Feb 21, 2024
1 parent 20de3f0 commit 64063d3
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 79 deletions.
2 changes: 1 addition & 1 deletion doc/install.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
+
Unix and Windows::
+
Download a Jason release from link:https://github.com/jason-lang/jason/releases[here] (download the file named `jason-bin-.....zip`) and decompress it. The zip file contains documentation, examples, and a sub-directory `bin` with the file *`jason`*. It is a unix executable file, if not, change its properties with `chmod +x jason`. Finally, link:https://www.computerhope.com/issues/ch000549.htm[adds the directory `bin` in your machine `PATH`] so that the command `jason` can be executed in a terminal.
Download a Jason release from link:https://github.com/jason-lang/jason/releases[here] (download the file named `jason-bin-.....zip`) and decompress it. The zip file contains documentation, examples, and a subdirectory `bin` with the file *`jason`*. It is a unix executable file, if not, change its properties with `chmod +x jason`. Finally, link:https://www.computerhope.com/issues/ch000549.htm[adds the directory `bin` in your machine `PATH`] so that the command `jason` can be executed in a terminal.
Linux::
You can use `apt-get` to install Jason (details link:https://github.com/chon-group/dpkg-jason[here]):
Expand Down
120 changes: 112 additions & 8 deletions jason-interpreter/src/main/java/jason/asSemantics/Agent.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -79,7 +78,7 @@ public Agent() {

/**
* Set up the default agent configuration.
*
* <p>
* Creates the agent class defined by <i>agClass</i>, default is jason.asSemantics.Agent.
* Creates the TS for the agent.
* Creates the belief base for the agent.
Expand All @@ -90,7 +89,7 @@ public static Agent create(AgArch arch, String agClass, ClassParameters bbPars,

new TransitionSystem(ag, null, stts, arch);

BeliefBase bb = null;
BeliefBase bb;
if (bbPars == null)
bb = new DefaultBeliefBase();
else
Expand All @@ -108,10 +107,11 @@ public static Agent create(AgArch arch, String agClass, ClassParameters bbPars,
//}
}

private boolean considerToaddMIForThisAgent = true;
private boolean considerToAddMIForThisAgent = true;
public void setConsiderToAddMIForThisAgent(boolean add) {
considerToaddMIForThisAgent = add;
considerToAddMIForThisAgent = add;
}

/** Initialises the TS and other components of the agent */
public void initAg() {
if (bb == null) bb = new DefaultBeliefBase();
Expand All @@ -129,7 +129,7 @@ public void initAg() {
//if (ts.getSettings().hasQueryProfiling()) qProfiling = new QueryProfiling(this);
//if (ts.getSettings().hasQueryCache()) qCache = new QueryCacheSimple(this, qProfiling);

if (considerToaddMIForThisAgent)
if (considerToAddMIForThisAgent)
addToMindInspectorWeb();
}

Expand Down Expand Up @@ -252,7 +252,7 @@ public void stopAg() {
* A new TS is created (based on the cloned circumstance).
*/
public Agent clone(AgArch arch) {
Agent a = null;
Agent a;
try {
a = this.getClass().getConstructor().newInstance();
} catch (InstantiationException e1) {
Expand Down Expand Up @@ -645,6 +645,110 @@ public ActionExec selectAction(Queue<ActionExec> actions) {
return actions.poll();
}

public List<Option> relevantPlans(Trigger teP, Event evt) throws JasonException {
Trigger te = teP.clone();
List<Option> rp = null;

// gets the proper plan library (root, inner scope, ...)
PlanLibrary plib = getPL();
if (evt != null && evt.isInternal() && !evt.getIntention().isFinished()) {
Plan p = evt.getIntention().peek().getPlan();
if (p.hasSubPlans()) {
plib = p.getSubPlans();
} else if (p.getScope() != null) {
plib = p.getScope();
}
}


while (plib != null) {
List<Plan> candidateRPs = plib.getCandidatePlans(te);
if (candidateRPs != null) {
for (Plan pl : candidateRPs) {

Unifier relUn = null;
if (evt != null && evt.isInternal()) {
// use IM vars in the context for sub-plans (new in JasonER)
for (IntendedMeans im: evt.getIntention()) {
if (im.getPlan().hasSubPlans() && im.getPlan().getSubPlans().get(pl.getLabel()) != null) {
relUn = im.triggerUnif.clone();
break;
}
}
}

relUn = pl.isRelevant(te, relUn);
if (relUn != null) {
if (rp == null) rp = new LinkedList<>();
rp.add(new Option(pl, relUn, evt));
}
}
}
plib = plib.getFather();
}

/* (previous to JasonER)
List<Plan> candidateRPs = ag.pl.getCandidatePlans(te);
if (candidateRPs != null) {
for (Plan pl : candidateRPs) {
Unifier relUn = pl.isRelevant(te, null);
if (relUn != null) {
if (rp == null) rp = new LinkedList<>();
rp.add(new Option(pl, relUn));
}
}
}*/
return rp;
}

public List<Option> applicablePlans(List<Option> rp) throws JasonException {
synchronized (getTS().getC().syncApPlanSense) {
List<Option> ap = null;
if (rp != null) {
for (Option opt: rp) {
LogicalFormula context = opt.getPlan().getContext();
if (getLogger().isLoggable(Level.FINE))
getLogger().log(Level.FINE, "option for "+getTS().getC().SE.getTrigger()+" is plan "+opt.getPlan().getLabel() + " " + opt.getPlan().getTrigger() + " : " + context + " -- with unification "+opt.getUnifier());

if (context == null) { // context is true
if (ap == null) ap = new LinkedList<>();
ap.add(opt);
if (getLogger().isLoggable(Level.FINE))
getLogger().log(Level.FINE, " "+opt.getPlan().getLabel() + " is applicable with unification "+opt.getUnifier());
} else {
boolean allUnifs = opt.getPlan().isAllUnifs();

Iterator<Unifier> r = context.logicalConsequence(this, opt.getUnifier());
boolean isApplicable = false;
if (r != null) {
while (r.hasNext()) {
isApplicable = true;
opt.setUnifier(r.next());

if (ap == null) ap = new LinkedList<>();
ap.add(opt);

if (getLogger().isLoggable(Level.FINE))
getLogger().log(Level.FINE, " "+opt.getPlan().getLabel() + " is applicable with unification "+opt.getUnifier());

if (!allUnifs) break; // returns only the first unification
if (r.hasNext()) {
// create a new option for the next loop step
opt = new Option(opt.getPlan(), null, opt.getEvt());
}
}
}

if (!isApplicable && getLogger().isLoggable(Level.FINE))
getLogger().log(Level.FINE, " "+opt.getPlan().getLabel() + " is not applicable");
}
}
}
return ap;
}
}


/** TS Initialisation (called by the AgArch) */
public void setTS(TransitionSystem ts) {
this.ts = ts;
Expand Down Expand Up @@ -896,7 +1000,7 @@ public List<Literal>[] brf(Literal beliefToAdd, Literal beliefToDel, Intention
}

if (beliefToDel != null) {
Unifier u = null;
Unifier u;
try {
u = i.peek().unif; // get from current intention
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,51 +1,17 @@
package jason.asSemantics;

import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import jason.JasonException;
import jason.NoValueException;
import jason.RevisionFailedException;
import jason.architecture.AgArch;
import jason.asSemantics.GoalListener.GoalStates;
import jason.asSyntax.ASSyntax;
import jason.asSyntax.Atom;
import jason.asSyntax.BinaryStructure;
import jason.asSyntax.InternalActionLiteral;
import jason.asSyntax.ListTerm;
import jason.asSyntax.ListTermImpl;
import jason.asSyntax.Literal;
import jason.asSyntax.LiteralImpl;
import jason.asSyntax.LogicalFormula;
import jason.asSyntax.NumberTerm;
import jason.asSyntax.ObjectTermImpl;
import jason.asSyntax.Plan;
import jason.asSyntax.PlanBody;
import jason.asSyntax.*;
import jason.asSyntax.PlanBody.BodyType;
import jason.asSyntax.PlanBodyImpl;
import jason.pl.PlanLibrary;
import jason.asSyntax.SourceInfo;
import jason.asSyntax.StringTermImpl;
import jason.asSyntax.Structure;
import jason.asSyntax.Term;
import jason.asSyntax.Trigger;
import jason.asSyntax.Trigger.TEOperator;
import jason.asSyntax.Trigger.TEType;
import jason.asSyntax.UnnamedVar;
import jason.asSyntax.VarTerm;
import jason.asSyntax.parser.ParseException;
import jason.bb.BeliefBase;
import jason.pl.PlanLibrary;
import jason.runtime.Settings;
import jason.stdlib.add_nested_source;
import jason.stdlib.desire;
Expand All @@ -54,6 +20,14 @@
import jason.util.Config;
import jason.util.RunnableSerializable;

import java.io.Serial;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;


public class TransitionSystem implements Serializable {

Expand Down Expand Up @@ -290,7 +264,7 @@ private void applyProcMsg() throws JasonException {
if (m == null) return;

// get the content, it can be any term (literal, list, number, ...; see ask)
Term content = null;
Term content;
if (m.getPropCont() instanceof Term) {
content = (Term)m.getPropCont();
} else {
Expand Down Expand Up @@ -370,19 +344,23 @@ private void applyProcMsg() throws JasonException {

boolean added = false;
if (!setts.isSync() && !ag.getPL().hasUserKqmlReceivedPlans() && content.isLiteral() && !content.isList()) { // optimisation to jump kqmlPlans
if (m.getIlForce().equals("achieve") ) {
content = add_nested_source.addAnnotToList(content, new Atom(sender));
C.addEvent(new Event(new Trigger(TEOperator.add, TEType.achieve, (Literal)content), Intention.EmptyInt));
added = true;
} else if (m.getIlForce().equals("tell") ) {
content = add_nested_source.addAnnotToList(content, new Atom(sender));
getAg().addBel((Literal)content);
added = true;
} else if (m.getIlForce().equals("signal") ) {
content = add_nested_source.addAnnotToList(content, new Atom(sender));
((Literal)content).addAnnot(new Atom("signal"));
C.addEvent(new Event(new Trigger(TEOperator.add, TEType.signal, (Literal)content), Intention.EmptyInt));
added = true;
switch (m.getIlForce()) {
case "achieve" -> {
content = add_nested_source.addAnnotToList(content, new Atom(sender));
C.addEvent(new Event(new Trigger(TEOperator.add, TEType.achieve, (Literal) content), Intention.EmptyInt));
added = true;
}
case "tell" -> {
content = add_nested_source.addAnnotToList(content, new Atom(sender));
getAg().addBel((Literal) content);
added = true;
}
case "signal" -> {
content = add_nested_source.addAnnotToList(content, new Atom(sender));
((Literal) content).addAnnot(new Atom("signal"));
C.addEvent(new Event(new Trigger(TEOperator.add, TEType.signal, (Literal) content), Intention.EmptyInt));
added = true;
}
}
}

Expand Down Expand Up @@ -544,7 +522,7 @@ private void applyClrSatInt() {
private void applyRelPl() throws JasonException {
if (C.SE.getOption() == null) { // no option yet
// get all relevant plans for the selected event
C.RP = relevantPlans(C.SE.trigger, C.SE);
C.RP = getAg().relevantPlans(C.SE.trigger, C.SE);

// Rule Rel1
if (C.RP != null || setts.retrieve())
Expand All @@ -559,7 +537,7 @@ private void applyRelPl() throws JasonException {

private void applyApplPl() throws JasonException {
if (C.SE.getOption() == null) { // no option yet
C.AP = applicablePlans(C.RP);
C.AP = getAg().applicablePlans(C.RP);

// Rule Appl1
if (C.AP != null || setts.retrieve())
Expand Down Expand Up @@ -1296,7 +1274,7 @@ private void joinRenamedVarsIntoIntentionUnifier(IntendedMeans im, Unifier value
/* auxiliary functions for the semantic rules */
/**********************************************/

public List<Option> relevantPlans(Trigger teP, Event evt) throws JasonException {
/*public List<Option> relevantPlans(Trigger teP, Event evt) throws JasonException {
Trigger te = teP.clone();
List<Option> rp = null;
Expand Down Expand Up @@ -1338,21 +1316,11 @@ public List<Option> relevantPlans(Trigger teP, Event evt) throws JasonException
plib = plib.getFather();
}
/* (previous to JasonER)
List<Plan> candidateRPs = ag.pl.getCandidatePlans(te);
if (candidateRPs != null) {
for (Plan pl : candidateRPs) {
Unifier relUn = pl.isRelevant(te, null);
if (relUn != null) {
if (rp == null) rp = new LinkedList<>();
rp.add(new Option(pl, relUn));
}
}
}*/
return rp;
}
*/

public List<Option> applicablePlans(List<Option> rp) throws JasonException {
/*public List<Option> applicablePlans(List<Option> rp) throws JasonException {
synchronized (C.syncApPlanSense) {
List<Option> ap = null;
if (rp != null) {
Expand Down Expand Up @@ -1400,6 +1368,7 @@ public List<Option> applicablePlans(List<Option> rp) throws JasonException {
return ap;
}
}
*/

public boolean updateEvents(List<Literal>[] result, Intention focus) {
if (result == null) return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public Object execute(TransitionSystem ts, Unifier un, Term[] args) throws Excep
te.setLiteral(te.getLiteral().forceFullLiteralImpl());
te.getLiteral().addSource(new UnnamedVar());
}
List<Option> rp = ts.relevantPlans(te, null);
List<Option> rp = ts.getAg().relevantPlans(te, null);
if (rp != null) {
for (Option opt: rp) {
Plan np = (Plan)opt.getPlan().clone();
Expand Down
8 changes: 4 additions & 4 deletions jason-interpreter/src/test/java/test/TSTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ public void testRelevant() throws ParseException, JasonException {
Trigger te1 = ASSyntax.parseTrigger("+a(10)");

try {
List<Option> rp = ts.relevantPlans(te1, null);
List<Option> rp = ts.getAg().relevantPlans(te1, null);
// System.out.println("RP="+rp);
assertEquals(rp.size(), 2);

rp = ts.applicablePlans(rp);
rp = ts.getAg().applicablePlans(rp);
// System.out.println("AP="+rp);
assertEquals(rp.size(), 1);

Expand All @@ -55,11 +55,11 @@ public void testRelevant() throws ParseException, JasonException {
Trigger te2 = ASSyntax.parseTrigger("+a(20)");

try {
List<Option> rp = ts.relevantPlans(te2, null);
List<Option> rp = ts.getAg().relevantPlans(te2, null);
// System.out.println("RP="+rp);
assertEquals(rp.size(), 2);

rp = ts.applicablePlans(rp);
rp = ts.getAg().applicablePlans(rp);
// System.out.println("AP="+rp);
assertEquals(rp.size(), 1);

Expand Down

0 comments on commit 64063d3

Please # to comment.