
jason.asSemantics.Intention Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jason Show documentation
Show all versions of jason Show documentation
Jason is a fully-fledged interpreter for an extended version of AgentSpeak, a BDI agent-oriented logic programming language.
//----------------------------------------------------------------------------
// Copyright (C) 2003 Rafael H. Bordini, Jomi F. Hubner, et al.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// To contact the authors:
// http://www.inf.ufrgs.br/~bordini
// http://www.das.ufsc.br/~jomi
//
//----------------------------------------------------------------------------
package jason.asSemantics;
import jason.asSyntax.ListTerm;
import jason.asSyntax.ListTermImpl;
import jason.asSyntax.NumberTermImpl;
import jason.asSyntax.PlanLibrary;
import jason.asSyntax.Structure;
import jason.asSyntax.Term;
import jason.asSyntax.Trigger;
import jason.asSyntax.Trigger.TEOperator;
import jason.util.Pair;
import java.io.Serializable;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicInteger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Represents and Intention (a stack of IntendedMeans).
*
* The comparable sorts the intentions based on the atomic property:
* atomic intentions comes first.
*
* @author Jomi & Rafael
*/
public class Intention implements Serializable, Comparable, Iterable {
private static final long serialVersionUID = 1L;
public static final Intention EmptyInt = null;
private static AtomicInteger idCount = new AtomicInteger(0);
private int id;
private int atomicCount = 0; // number of atomic intended means in the intention
private boolean isSuspended = false;
private Deque intendedMeans = new ArrayDeque();
//private Trigger initialTrigger = null; // just for additional information/debug (not really necessary)
//static private Logger logger = Logger.getLogger(Intention.class.getName());
public Intention() {
id = idCount.incrementAndGet();
}
public int getId() {
return id;
}
public void push(IntendedMeans im) {
intendedMeans.push(im);
if (im.isAtomic())
atomicCount++;
//if (initialTrigger == null)
// initialTrigger = im.getTrigger();
}
public IntendedMeans peek() {
return intendedMeans.peek();
}
public IntendedMeans pop() {
IntendedMeans top = intendedMeans.pop();
if (isAtomic() && top.isAtomic()) {
atomicCount--;
/* for (IntendedMeans im : intendedMeans) {
if (im.isAtomic()) {
isAtomic = true;
break;
}
}*/
}
return top;
}
public boolean isAtomic() {
return atomicCount > 0;
}
public void setAtomic(int a) { // used for testing
atomicCount = a;
}
public Iterator iterator() {
return intendedMeans.iterator();
}
public boolean isFinished() {
return intendedMeans.isEmpty();
}
public int size() {
return intendedMeans.size();
}
public void clearIM() {
intendedMeans.clear();
}
public void setSuspended(boolean b) {
isSuspended = b;
}
public boolean isSuspended() {
return isSuspended;
}
/** returns the IntendedMeans with TE = g, returns null if there isn't one */
public IntendedMeans getIM(Trigger g, Unifier u) {
for (IntendedMeans im : intendedMeans)
//System.out.println(g + " = "+ im.getTrigger()+" = "+u.unifies(g, im.getTrigger()));
if (u.unifies(g, im.getTrigger()))
return im;
return null;
}
public IntendedMeans getBottom() {
return intendedMeans.getLast();
}
/** returns true if the intention has an IM where TE = g, using u to verify equality */
public boolean hasTrigger(Trigger g, Unifier u) {
//return getIM(g,u) != null;
for (IntendedMeans im : intendedMeans)
if (u.unifies(g, im.getTrigger()))
return true;
return false;
}
/** remove all IMs until the IM with trigger te */
public boolean dropGoal(Trigger te, Unifier un) {
IntendedMeans im = getIM(te, un);
if (im != null) {
// remove the IMs until im-1
while (peek() != im) {
pop();
}
pop(); // remove im
return true;
}
return false;
}
public void fail(Circumstance c) {
}
public Pair findEventForFailure(Trigger tevent, PlanLibrary pl, Circumstance c) {
Trigger failTrigger = new Trigger(TEOperator.del, tevent.getType(), tevent.getLiteral());
Iterator ii = iterator();
int posInStak = size();
synchronized (pl.getLock()) {
while (!pl.hasCandidatePlan(failTrigger) && ii.hasNext()) {
// TODO: pop IM until +!g or *!g (this TODO is valid only if meta events are pushed on top of the intention)
// If *!g is found first, no failure event
// - while popping, if some meta event (* > !) is in the stack, stop and simple pop instead of producing an failure event
IntendedMeans im = ii.next();
tevent = im.getTrigger();
failTrigger = new Trigger(TEOperator.del, tevent.getType(), tevent.getLiteral());
posInStak--;
}
if (tevent.isGoal() && tevent.isAddition() && pl.hasCandidatePlan(failTrigger))
return new Pair(new Event(failTrigger.clone(), this), posInStak);
else
return new Pair(null, 0);
}
}
/** implements atomic intentions > not atomic intentions */
public int compareTo(Intention o) {
if (o.atomicCount > this.atomicCount) return 1;
if (this.atomicCount > o.atomicCount) return -1;
if (o.id > this.id) return 1;
if (this.id > o.id) return -1;
return 0;
}
public boolean equals(Object o) {
if (o == null) return false;
if (o == this) return true;
if (o instanceof Intention) return ((Intention)o).id == this.id;
return false;
}
public int hashCode() {
return id;
}
public Intention clone() {
Intention i = new Intention();
i.id = id;
i.atomicCount = atomicCount;
i.intendedMeans = new ArrayDeque();
for (IntendedMeans im: intendedMeans) {
i.intendedMeans.add((IntendedMeans)im.clone());
}
return i;
}
// used by fork
public void copyTo(Intention i) {
i.atomicCount = atomicCount;
i.intendedMeans = new ArrayDeque(intendedMeans);
}
public String toString() {
StringBuilder s = new StringBuilder("intention "+id+": \n");
int i = 0;
for (IntendedMeans im: intendedMeans) {
s.append(" " + im + "\n");
if (i++ > 40) {
s.append("... more "+ (size()-40) + " intended means!\n");
break;
}
}
if (isFinished())
s.append("");
return s.toString();
}
public Term getAsTerm() {
Structure intention = new Structure("intention");
intention.addTerm(new NumberTermImpl(getId()));
ListTerm lt = new ListTermImpl();
for (IntendedMeans im: intendedMeans)
lt.add(im.getAsTerm());
intention.addTerm(lt);
return intention;
}
/** get as XML */
public Element getAsDOM(Document document) {
Element eint = (Element) document.createElement("intention");
eint.setAttribute("id", id + "");
for (IntendedMeans im: intendedMeans)
eint.appendChild(im.getAsDOM(document));
//if (intendedMeans.isEmpty())
// eint.appendChild( initialTrigger.getAsDOM(document));
eint.setAttribute("finished", ""+isFinished());
eint.setAttribute("suspended", ""+isSuspended());
return eint;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy