Beispiel #1
0
 private Value encodeValue(Object value) {
   if (value instanceof Actor) {
     Actor actor = (Actor) value;
     return new Term(REF, new Int(actor.getId()));
   }
   if (value instanceof Closure) {
     Closure fun = (Closure) value;
     return new Term(Key.getKey("Closure"), new Str(fun.getName()), new Int(fun.getArity()));
   }
   if (value instanceof Integer) return new Int((int) value);
   if (value instanceof String) return new Str((String) value);
   if (value instanceof Boolean) {
     Boolean b = (Boolean) value;
     if (b.booleanValue()) return new Term(Key.getKey("True"));
     else return new Term(Key.getKey("False"));
   }
   if (value instanceof actors.Term) {
     actors.Term t = (actors.Term) value;
     Term term = new Term(Key.getKey(t.getName().getString()));
     Value[] values = new Value[t.getValues().length];
     for (int i = 0; i < values.length; i++) values[i] = encodeValue(t.getValues()[i]);
     term.setValues(values);
     return term;
   }
   return new Str("Encode value error: " + value);
 }
Beispiel #2
0
 static {
   defRule(
       Key.getKey("state"),
       4,
       (history, time, endOfTime, values, succ, fail) ->
           HistoryPredicates.satisfyState(
               history, time, endOfTime, values[0], values[1], values[2], values[3], succ, fail));
   defRule(
       Key.getKey("actor"),
       3,
       (history, time, endOfTime, values, succ, fail) ->
           HistoryPredicates.satisfyActor(
               history, 0, time, endOfTime, values[0], values[1], values[2], succ, fail));
   defRule(
       Key.getKey("send"),
       4,
       (history, time, endOfTime, values, succ, fail) ->
           HistoryPredicates.satisfySend(
               history, 0, time, endOfTime, values[0], values[1], values[2], values[3], succ,
               fail));
 }
Beispiel #3
0
 public void state(int id, String name, Value value, int time) {
   if (!stateEvents.containsKey(id)) stateEvents.put(id, new Hashtable<Key, Stack<State>>());
   Hashtable<Key, Stack<State>> table = stateEvents.get(id);
   Key key = Key.getKey(name);
   if (!table.containsKey(key)) table.put(key, new Stack<State>());
   Stack<State> stack = table.get(key);
   if (stack.isEmpty()) stack.push(new State(id, key, value, time));
   else {
     State state = stack.peek();
     boolean changed = false;
     if (value == null && state.getValue() != null) changed = true;
     if (state.getValue() == null && value != null) changed = true;
     if (state.getValue() != null && value != null && !state.getValue().equals(value))
       changed = true;
     if (changed) {
       stack.push(new State(id, key, value, time));
     }
   }
 }
Beispiel #4
0
 private Key[] toKeys(String[] exports) {
   Key[] keys = new Key[exports.length];
   for (int i = 0; i < exports.length; i++)
     if (exports[i] != null) keys[i] = Key.getKey(exports[i]);
   return keys;
 }
Beispiel #5
0
public class History implements Serializable {

  public static final Hashtable<Key, RuleHandler> handlers = new Hashtable<Key, RuleHandler>();
  public static final Hashtable<Key, Integer> arity = new Hashtable<Key, Integer>();

  public static Key REF = Key.getKey("Ref");

  static {
    defRule(
        Key.getKey("state"),
        4,
        (history, time, endOfTime, values, succ, fail) ->
            HistoryPredicates.satisfyState(
                history, time, endOfTime, values[0], values[1], values[2], values[3], succ, fail));
    defRule(
        Key.getKey("actor"),
        3,
        (history, time, endOfTime, values, succ, fail) ->
            HistoryPredicates.satisfyActor(
                history, 0, time, endOfTime, values[0], values[1], values[2], succ, fail));
    defRule(
        Key.getKey("send"),
        4,
        (history, time, endOfTime, values, succ, fail) ->
            HistoryPredicates.satisfySend(
                history, 0, time, endOfTime, values[0], values[1], values[2], values[3], succ,
                fail));
  }

  public static void defRule(Key name, int args, RuleHandler handler) {
    handlers.put(name, handler);
    arity.put(name, args);
  }

  public static History inflate(String path) {
    FileInputStream fin;
    try {
      fin = new FileInputStream(path);
      ObjectInputStream in = new ObjectInputStream(fin);
      Object o = in.readObject();
      in.close();
      if (o != null && o instanceof History) {
        History history = (History) o;
        int b = history.behaviourChangedEvents.size();
        int c = history.consumeEvents.size();
        int a = history.newActorEvents.size();
        int s = history.sendEvents.size();
        int u = history.stateEvents.size();
        System.out.println(
            "[History "
                + path
                + " become="
                + b
                + " consume="
                + c
                + " actor="
                + a
                + " send="
                + s
                + " state="
                + u
                + " time=["
                + history.getStartOfTime()
                + ","
                + history.endOfTime
                + "]]");
        return history;
      } else throw new Error("expecting a history " + o);
    } catch (IOException | ClassNotFoundException e) {
      throw new Error(e.toString());
    }
  }

  int startOfTime;
  int endOfTime;
  Vector<BehaviourChanged> behaviourChangedEvents = new Vector<BehaviourChanged>();
  Vector<Consume> consumeEvents = new Vector<Consume>();
  Vector<NewActor> newActorEvents = new Vector<NewActor>();
  Vector<Send> sendEvents = new Vector<Send>();
  Hashtable<Integer, Hashtable<Key, Stack<State>>> stateEvents =
      new Hashtable<Integer, Hashtable<Key, Stack<State>>>();

  public History() {}

  public void behaviourChanged(
      Actor actor, Behaviour oldBehaviour, Behaviour newBehaviour, int time) {
    behaviourChangedEvents.add(
        new BehaviourChanged(actor.getId(), oldBehaviour.getName(), newBehaviour.getName(), time));
  }

  public void consume(Actor actor, Message message) {
    consumeEvents.add(new Consume(actor.getId(), encodeValue(message), Actor.getTime()));
  }

  private Value encodeValue(Object value) {
    if (value instanceof Actor) {
      Actor actor = (Actor) value;
      return new Term(REF, new Int(actor.getId()));
    }
    if (value instanceof Closure) {
      Closure fun = (Closure) value;
      return new Term(Key.getKey("Closure"), new Str(fun.getName()), new Int(fun.getArity()));
    }
    if (value instanceof Integer) return new Int((int) value);
    if (value instanceof String) return new Str((String) value);
    if (value instanceof Boolean) {
      Boolean b = (Boolean) value;
      if (b.booleanValue()) return new Term(Key.getKey("True"));
      else return new Term(Key.getKey("False"));
    }
    if (value instanceof actors.Term) {
      actors.Term t = (actors.Term) value;
      Term term = new Term(Key.getKey(t.getName().getString()));
      Value[] values = new Value[t.getValues().length];
      for (int i = 0; i < values.length; i++) values[i] = encodeValue(t.getValues()[i]);
      term.setValues(values);
      return term;
    }
    return new Str("Encode value error: " + value);
  }

  public Vector<BehaviourChanged> getBehaviourChangedEvents() {
    return behaviourChangedEvents;
  }

  public Vector<Consume> getConsumeEvents() {
    return consumeEvents;
  }

  public int getEndOfTime() {
    return endOfTime;
  }

  public int getStartOfTime() {
    return startOfTime;
  }

  public void setStartOfTime(int startOfTime) {
    this.startOfTime = startOfTime;
  }

  public Vector<NewActor> getNewActorEvents() {
    return newActorEvents;
  }

  public Vector<Send> getSendEvents() {
    return sendEvents;
  }

  public boolean maybeFact(Key name, Value[] values) {
    return (handlers.containsKey(name) && arity.get(name) == values.length);
  }

  public void newActor(Actor actor, int time) {
    newActorEvents.add(new NewActor(actor.getId(), actor.getBehaviour().getName(), time));
  }

  public void reset() {
    behaviourChangedEvents.clear();
    consumeEvents.clear();
    newActorEvents.clear();
    sendEvents.clear();
    stateEvents.clear();
  }

  public void satisfy(
      int time, int endOfTime, Key name, Value[] values, Consumer<Fail> succ, Fail fail) {
    if (handlers.containsKey(name) && arity.get(name) == values.length)
      handlers.get(name).satisfy(this, time, endOfTime, values, succ, fail);
    else fail.fail();
  }

  public void send(Actor source, Actor target, Message message, int time) {
    sendEvents.add(new Send(source.getId(), target.getId(), encodeValue(message.getValue()), time));
  }

  public void serialize(String path) {
    File file = new File(path);
    OutputStream fout;
    try {
      fout = new FileOutputStream(file);
      ObjectOutputStream out = new ObjectOutputStream(fout);
      out.writeObject(this);
      out.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public void setBehaviourChangedEvents(Vector<BehaviourChanged> behaviourChangedEvents) {
    this.behaviourChangedEvents = behaviourChangedEvents;
  }

  public void setConsumeEvents(Vector<Consume> consumeEvents) {
    this.consumeEvents = consumeEvents;
  }

  public void setEndOfTime(int endOfTime) {
    this.endOfTime = endOfTime;
  }

  public void setNewActorEvents(Vector<NewActor> newActorEvents) {
    this.newActorEvents = newActorEvents;
  }

  public void setSendEvents(Vector<Send> sendEvents) {
    this.sendEvents = sendEvents;
  }

  public Hashtable<Integer, Hashtable<Key, Stack<State>>> getStateEvents() {
    return stateEvents;
  }

  public void state(Actor a, String name, Object o, int time) {

    // Record the state of the actor in the history. Note that there are
    // state values that cannot be encoded in a history. These are returned
    // as null from encodeValue...

    Value value = encodeValue(o);
    if (value != null) state(a.getId(), name, value, time);
  }

  public void state(int id, String name, Value value, int time) {
    if (!stateEvents.containsKey(id)) stateEvents.put(id, new Hashtable<Key, Stack<State>>());
    Hashtable<Key, Stack<State>> table = stateEvents.get(id);
    Key key = Key.getKey(name);
    if (!table.containsKey(key)) table.put(key, new Stack<State>());
    Stack<State> stack = table.get(key);
    if (stack.isEmpty()) stack.push(new State(id, key, value, time));
    else {
      State state = stack.peek();
      boolean changed = false;
      if (value == null && state.getValue() != null) changed = true;
      if (state.getValue() == null && value != null) changed = true;
      if (state.getValue() != null && value != null && !state.getValue().equals(value))
        changed = true;
      if (changed) {
        stack.push(new State(id, key, value, time));
      }
    }
  }

  public History getSnapshot(int time) {
    // Create a snapshot of the receiver at the supplied time...
    History snapshot = new History();
    snapshot.startOfTime = time;
    snapshot.endOfTime = time;
    snapshot.behaviourChangedEvents = new Vector<BehaviourChanged>();
    snapshot.consumeEvents = new Vector<Consume>();
    snapshot.newActorEvents = new Vector<NewActor>();
    snapshot.sendEvents = new Vector<Send>();
    snapshot.stateEvents = new Hashtable<Integer, Hashtable<Key, Stack<State>>>();
    for (NewActor newActor : newActorEvents) {
      if (newActor.getTime() <= time) {
        BehaviourChanged b = null;
        for (BehaviourChanged b1 : behaviourChangedEvents) {
          if (b1.getId() == newActor.getId()
              && b1.getTime() <= time
              && b1.getTime() > newActor.getTime()
              && (b == null || b1.getTime() > b.getTime())) b = b1;
        }
        if (b == null)
          snapshot.newActorEvents.add(
              new NewActor(newActor.getId(), newActor.getBehaviour(), time));
        else snapshot.newActorEvents.add(new NewActor(newActor.getId(), b.getNewBehaviour(), time));
      }
    }
    for (Consume consume : consumeEvents) {
      if (consume.getTime() == time) snapshot.consumeEvents.add(consume);
    }
    for (Send send : sendEvents) {
      if (send.getTime() == time) snapshot.sendEvents.add(send);
    }
    for (int id : stateEvents.keySet()) {
      for (Key field : stateEvents.get(id).keySet()) {
        Stack<State> stack = stateEvents.get(id).get(field);
        if (!stack.isEmpty()) {
          State state = stack.peek();
          if (state.getTime() <= time)
            snapshot.state(id, field.getString(), state.getValue(), time);
        }
      }
    }
    return snapshot;
  }
}