
astra.core.Intention Maven / Gradle / Ivy
package astra.core;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;
import astra.core.Agent.Promise;
import astra.event.Event;
import astra.event.GoalEvent;
import astra.event.ScopedGoalEvent;
import astra.formula.Formula;
import astra.formula.Goal;
import astra.formula.Predicate;
import astra.formula.ScopedGoal;
import astra.reasoner.util.BindingsEvaluateVisitor;
import astra.reasoner.util.ContextEvaluateVisitor;
import astra.statement.StatementHandler;
import astra.statement.Subgoal;
import astra.term.FormulaTerm;
import astra.term.ModuleTerm;
import astra.term.NullTerm;
import astra.term.Operator;
import astra.term.Primitive;
import astra.term.Term;
import astra.term.Variable;
public class Intention {
public int age = 0;
Map> actionParams = new HashMap<>();
Stack failureTrace;
String failureReason;
private Throwable exception;
public Agent agent;
public Event event;
private Rule rule;
Map bindings;
boolean suspended = false;
boolean failed = false;
boolean recovering = false;
boolean hasGoalRule = false;
Stack executors = new Stack<>();
public Intention(Agent agent, Event event, Rule rule, Map bindings) {
this.agent = agent;
this.event = event;
this.bindings = bindings;
this.rule = rule;
hasGoalRule = rule instanceof GoalRule;
executors.push(new RuleExecutor(event, rule, bindings, null, this));
}
public synchronized boolean execute() {
if (!executors.isEmpty()) {
RuleExecutor executor = executors.peek();
try {
boolean result = executor.execute(this);
if (!this.isSuspended() && !result && !GoalRule.class.isInstance(executor.rule())) {
// System.out.println("\t\t\tPOPPING the executor");
executors.pop();
if (executor.parent() != null) executor.parent().updateRuleBindings(executor.bindings(), executor.getUnboundBindings());
}
} catch (Throwable e) {
e.printStackTrace();
this.failed("Error executing statement: " + executor.getNextStatment().toString(), e);
executor.printStackTrace();
}
}
return !executors.isEmpty();
}
public Module getModule(String classname, String key) {
return agent.getModule(classname,key);
}
@SuppressWarnings({ "unchecked" })
public T evaluate(Term term) {
// System.out.println("Evaluating: " + term);
if (term instanceof Primitive) {
// System.out.println("Val: " + ((Primitive) term).value().getClass().getCanonicalName());
return ((Primitive) term).value();
}
if (term instanceof Variable) {
Term val = getValue((Variable) term);
// System.out.println("[" + agent.name() + "] Value for variable: " + term + " is: " + val);
if (val == null || term.matches(val)) {
ActionParam param = new ActionParam<>();
actionParams.put((Variable) term, param);
return (T) param;
}
if (val instanceof NullTerm) {
return null;
}
return evaluate(val);
}
if (term instanceof Operator || term instanceof ModuleTerm) {
// System.out.println("Here: " + term);
// System.out.println(this.bindings());
Term t = (Term) term.accept(new ContextEvaluateVisitor(this));
if (t instanceof Primitive) {
return ((Primitive) t).value();
} else {
return (T) t;
}
}
if (term instanceof FormulaTerm) {
return (T) ((FormulaTerm) term).value();
}
if (term instanceof astra.term.ListTerm) {
// System.out.println("evaluating: " + term);
return (T) term.accept(new ContextEvaluateVisitor(this, false));
}
if (term instanceof astra.term.Funct) {
return (T) term.accept(new ContextEvaluateVisitor(this));
}
if ((term instanceof astra.term.Head) || (term instanceof astra.term.Tail) || (term instanceof astra.term.AtIndex)) {
Term _term = (Term) term.accept(new ContextEvaluateVisitor(this));
return evaluate(_term);
}
System.out.println("term: " + term);
System.out.println("EVALUATE: " + term.getClass().getName());
return null;
}
public Term getValue(Variable term) {
Term value = null;
int i = executors.size()-1;
value = executors.get(i--).getValue(term);
while (value == null && i >= 0) {
RuleExecutor executor = executors.get(i--);
if (GoalRule.class.isInstance(executor.rule())) {
value = executor.getValue(term);
}
}
return value;
}
// synchronized
public void addSubGoal(Event event, Rule rule, Map bindings, RuleExecutor parent) {
if (rule instanceof GoalRule) hasGoalRule = true;
executors.push(new RuleExecutor(event, rule, bindings, parent, this));
}
/**
* Moves down through the ruleexecutor stack looking for a ruleexecutor that has the variable being updated...
* @param term the variable to be updated
* @param logic the new value to be associated with the variable
* @return true if it was updated, false otherwise
*/
public boolean updateVariable(Variable term, Term logic) {
boolean updated = false;
int i = executors.size()-1;
while (!updated && i >= 0) updated = executors.get(i--).updateVariable(term, logic);
return updated;
}
public String toString() {
StringBuilder out = new StringBuilder();
for (int i=executors.size()-1 ; i >= 0; i--) {
out.append(executors.get(i).event()).append("\n");
}
return out.toString();
}
public void failed(String reason) {
failed(reason, null);
}
public void failed(String reason, Throwable exception) {
failed = true;
failureTrace = new Stack<>();
for (RuleExecutor executor : executors) {
executor.buildFailureTrace(failureTrace);
}
failureReason = reason;
this.exception = exception;
}
public boolean isFailed() {
return failed;
}
public void printStackTrace() {
if (failureTrace == null) return;
System.out.println("["+agent.name()+"] " + failureReason);
for (int i=failureTrace.size()-1; i >= 0; i--) {
if (failureTrace.get(i).statement() instanceof Subgoal||i == failureTrace.size()-1) {
System.out.print("["+agent.name()+"] " + failureTrace.get(i).statement().getASTRAClass() + "." + failureTrace.get(i));
if (failureTrace.get(i).statement().isLinkedToSource()) {
System.out.print(":" + failureTrace.get(i).statement().beginLine());
}
System.out.println();
}
}
System.out.println("["+agent.name()+"] " + event.toString());
if (exception != null) {
System.err.println("["+agent.name()+"] Caused By:");
exception.printStackTrace();
}
}
public boolean rollback() {
// DEAL WITH ROLLBACK...
while (!executors.isEmpty()) {
RuleExecutor executor = executors.peek();
if (executor.rollback(this)) {
failed = false;
resume();
return true;
}
executors.pop();
if (failed && executor.event() instanceof GoalEvent) {
GoalEvent goalEvent = (GoalEvent) executor.event();
GoalEvent removalEvent = new GoalEvent(Event.REMOVAL, goalEvent.goal(), this);
if (goalEvent.type == Event.ADDITION && agent.addEvent(removalEvent)) {
recovering = true;
failed = false;
return true;
}
}
}
return false;
}
public void addBelief(Predicate belief) {
agent.beliefs().addBelief(belief);
}
public void removeBelief(Predicate belief) {
// System.out.println("[Intention.removeBelief()] Removing: " + belief);
agent.beliefs().dropBelief(belief);
}
public void suspend() {
suspended = true;
}
public boolean isSuspended() {
return suspended;
}
public boolean isRecovering() {
return recovering;
}
public void resume() {
if (recovering) recovering = false;
suspended = false;
}
public void resetActionParams() {
actionParams.clear();
}
public void applyActionParams() {
for (Entry> entry : actionParams.entrySet()) {
this.updateVariable(entry.getKey(), entry.getValue().toLogic());
}
}
public void dumpStack() {
System.out.println("Intention State: " + (this.isActive() ? "ACTIVE":"SUSPENDED"));
for (int i=executors.size()-1 ; i >= 0; i--) {
System.out.println(i +". " + executors.get(i).event() +": "+executors.get(i).bindings());
}
System.out.println("\n\n"+generateIntentionTree());
}
public String generateIntentionTree() {
Set baseRules = new HashSet<>();
Map> children = new HashMap<>();
for (RuleExecutor executor:executors) {
if (executor.parent() == null) {
baseRules.add(executor.event().toString()+": "+executor.bindings());
} else {
String parent = executor.parent().event().toString()+": "+executor.parent().bindings();
List list = children.computeIfAbsent(parent, s->new LinkedList<>());
list.add(executor.event().toString()+": "+executor.bindings());
}
}
StringBuffer buf = new StringBuffer();
for (String node : baseRules) {
buf.append(node).append("\n");
addChildren(buf, node, children, "\t");
}
return buf.toString();
}
private void addChildren(StringBuffer buf, String node, Map> children, String tabs) {
List list = children.get(node);
if (list == null) return;
for (String item : list) {
buf.append(tabs).append(item).append("\n");
addChildren(buf, item, children, tabs+"\t");
}
}
public boolean addGoal(Goal goal) {
return agent.addEvent(new GoalEvent(Event.ADDITION, goal));
}
public boolean addScopedGoal(String scope, Goal goal) {
return agent.addEvent(new ScopedGoalEvent(Event.ADDITION, new ScopedGoal(scope, goal)));
}
public void notifyDone(String message) {
agent.notifyDone(new Agent.Notification(this, message));
}
public void notifyDone(String message, Throwable exception) {
agent.notifyDone(new Agent.Notification(this, message, exception));
}
public void schedule(Task task) {
agent.schedule(task);
}
public String name() {
return agent.name();
}
public Map query(Formula formula) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy