All Downloads are FREE. Search and download functionalities are using the official Maven repository.

astra.core.ASTRAClass Maven / Gradle / Ivy

There is a newer version: 1.4.2
Show newest version
package astra.core;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;

import astra.event.Event;
import astra.event.GoalEvent;
import astra.formula.Formula;
import astra.formula.Goal;
import astra.formula.Inference;
import astra.formula.Predicate;
import astra.reasoner.Queryable;
import astra.term.ListTerm;
import astra.term.Term;
import astra.tr.Function;

public abstract class ASTRAClass implements Queryable {
	Map> rules = new HashMap<>();
	Map functions = new HashMap<>();
	Map> inferences = new HashMap<>();
	List  ruleOrder = new LinkedList<>();
	private Set filter = new HashSet<>();

	private List linearization;
	private Class[] parents;
	private int distFromRoot = -1;

	public void setParents(Class[] parents) {
		this.parents = parents;
	}

	public boolean isRunnable() {
		GoalEvent event = new GoalEvent('+', new Goal(new Predicate("main", new Term[] { new ListTerm()})));
		for (ASTRAClass cls : linearization) {
			if (cls.rules.containsKey(event.signature())) return true;
		}
		return false;
	}

	public synchronized Agent newInstance(String name) throws AgentCreationException, ASTRAClassNotFoundException {
		if (Agent.hasAgent(name)) {
			throw new AgentCreationException("An agent with name: \"" + name + "\" already exists.");
		}
		
		Agent agent = new Agent(name);
		agent.setMainClass(this);
		
		return agent;
	}
	
	public abstract void initialize(Agent agent);
	
	public abstract Fragment createFragment(Agent agent) throws ASTRAClassNotFoundException;
	
	public List getLinearization() throws ASTRAClassNotFoundException {
		if (linearization==null) {
			linearization = new LinkedList<>();
			
			Queue queue = new PriorityQueue<>(1, (o1,o2) -> o1.getDistance()-o2.getDistance());
			
			Queue queue2 = new LinkedList<>();
			queue2.add(this);
			while (!queue2.isEmpty()) {
				ASTRAClass claz = queue2.poll();
				if (claz.parents != null) {
					for (int i=claz.parents.length-1; i>-1; i--) {
						ASTRAClass c = ASTRAClassLoader.getDefaultClassLoader().loadClass(claz.parents[i]);
						if (!queue.contains(c) && !queue2.contains(c)) {
							queue2.add(c);
						}
					}
					queue.add(claz);
				}
			}
			
			while (!queue.isEmpty()) {
				ASTRAClass claz = queue.poll();
				if (!linearization.contains(claz)) 
					linearization.add(0, claz);
			}
		}
		return linearization;
	}
	
	public int getDistance() {
		int maxDist;
		int d;
		if (distFromRoot==-1) {
			maxDist=0;
			if (parents != null) {
				for (Class parent : this.parents) {
					try {
						ASTRAClass cls = ASTRAClassLoader.getDefaultClassLoader().loadClass(parent);
						d = cls.getDistance();
						if (d > maxDist) maxDist = d;
					} catch (ASTRAClassNotFoundException e) {
						e.printStackTrace();
					}
				}
			}

			distFromRoot = maxDist+1;
		}
		return distFromRoot;
	}
	
	public String toString() {
		return "ASTRAClass:"+getClass().getCanonicalName();
	}
	
	public String getCanonicalName() {
		return getClass().getCanonicalName();
	}

	public List getRuleOrder() {
		return ruleOrder;
	}
	
	public void addRule(Rule rule) {
		ruleOrder.add(rule);
		List list = rules.get(rule.event.signature());
		if (list == null) {
			filter.add(rule.event.signature());
			list = new LinkedList<>();
			rules.put(rule.event.signature(), list);
		}
		
		list.add(rule);
	}
	
	public void addInference(Inference inference) {
		List list = inferences.get(inference.head().id());
		if (list == null) {
			list = new LinkedList<>();
			inferences.put(inference.head().id(), list);
		}
		
		list.add(inference);
	}
	
	public void addFunction(Function function) {
		if (functions.containsKey(function.identifier.id())) {
			System.out.println("Attempt to add duplicate function :" + function.identifier);
			return;
		}
		functions.put(function.identifier.id(), function);
	}
	
	public Set filter() {
		return filter;
	}

	public boolean handleEvent(Event event, Agent agent) {
		// System.out.println("["+agent.name()+"] Checking class: " + getClass().getCanonicalName());
		if (agent.trace()) System.out.println("["+agent.name()+"] Checking class: " + getClass().getCanonicalName());
		List list = rules.get(event.signature());
		// System.out.println("["+agent.name()+"] List: " + list);
		if (list == null) return false;
		
		for (Rule rule : list) {
			if (agent.trace()) System.out.println("["+agent.name()+"] \tChecking rule: " + rule.event);
			Map bindings = Helper.evaluateRule(agent, rule, event);
			if (bindings != null) {
				Object source = event.getSource();
				if (source != null) {
					Intention intention = null;
					if (Intention.class.isInstance(source)) {
						intention = (Intention) source;
						intention.addSubGoal(event, rule, bindings, null);
						if (agent.trace()) System.out.println("["+agent.name()+"] \tADDING SUBGOAL: " + rule.event + "\n\tbindings: " + bindings);
					} else if (RuleExecutor.class.isInstance(source)) {
						RuleExecutor executor = (RuleExecutor) source;
						intention = executor.intention();
						intention.addSubGoal(event, rule, bindings, executor);
						if (agent.trace()) System.out.println("["+agent.name()+"] \tADDING RULE SUBGOAL: " + rule.event + "\n\tbindings: " + bindings);
					}	
					intention.resume();
				} else {
					// Intention i = null;
					// System.out.println("["+agent.name()+"] \tCREATING NEW INTENTION: " + rule.event + "\n\tbindings: " + bindings);
					agent.addIntention(new Intention(agent, event, rule, bindings));
					// System.out.println(i.toString());
				}
				return true;
			}
		}
		if (agent.trace()) System.out.println("[" + agent.name() + "] FAILED to match event...");
		return false;
	}
	
	public static ASTRAClass forName(String url) throws ASTRAClassNotFoundException {
		return ASTRAClassLoader.getDefaultClassLoader().loadClass(url);
	}
	
	public static ASTRAClass forName(String _package, String url) throws ASTRAClassNotFoundException {
		if (_package == null) return forName(url);
		return ASTRAClassLoader.getDefaultClassLoader().loadClass(_package+"."+url);
	}

	public Function getFunction(Predicate predicate) {
		return functions.get(predicate.id());
	}

	public boolean hasFunctions() {
		return !functions.isEmpty();
	}

	public void addMatchingFormulae(Queue queue, Formula predicate) {
		if (predicate instanceof Predicate) {
			List list = inferences.get(((Predicate) predicate).id());
			if (list != null) queue.addAll(list);
		}
	}

	public Iterator iterator(Formula formula) {
		if (formula instanceof Predicate) {
			List list =  inferences.get(((Predicate) formula).id());
			return list == null ? Queryable.EMPTY_LIST.iterator():list.iterator();
		}
		return Queryable.EMPTY_LIST.iterator();
	}

	public boolean isSubclass(ASTRAClass cl) {
		try {
			for (ASTRAClass cls : cl.getLinearization()) {
				if (cls.getCanonicalName().equals(this.getCanonicalName())) return true;
			}
		} catch (ASTRAClassNotFoundException e) {
			e.printStackTrace();
		}
		return false;
	}

	public Map> rules() {
		return this.rules;
	}

	public Class[] getParents() {
		return parents;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy