public int bind(IModel model, VariableBindings variableBindings, boolean isIterative)
      throws CannotMatchException {
    int unresolved = 0;

    IChunk resolvedChunk = (IChunk) variableBindings.get(getVariableName());

    if (resolvedChunk == null && !isIterative)
      throw new CannotMatchException(
          new GeneralMatchFailure(this, String.format("%s is undefined", getVariableName())));

    try {
      if (resolvedChunk == null)
        unresolved = getRequest().bind(model, variableBindings, isIterative) + 1;
      else
        unresolved =
            getRequest()
                .bind(
                    model,
                    resolvedChunk.getSymbolicChunk().getName(),
                    resolvedChunk.getSymbolicChunk(),
                    variableBindings,
                    isIterative);
    } catch (CannotMatchException cme) {
      cme.getMismatch().setCondition(this);
      throw cme;
    }

    return unresolved;
  }
  public double computeEncodingTime(IChunk visualChunk, IVisualModule module) {
    IChunk error = module.getModel().getDeclarativeModule().getErrorChunk();

    if (error.equals(visualChunk))
      return module.getModel().getProceduralModule().getDefaultProductionFiringTime();

    return 0.085;
  }
Exemple #3
0
  @Override
  public void fillSlotValues(
      ChunkTypeRequest mutableRequest,
      IIdentifier identifier,
      IChunk encodedChunk,
      ChunkTypeRequest originalSearchRequest) {
    String[] kinds = _currentKindMap.get(identifier);

    if (kinds != null)
      for (String kind : kinds)
        try {
          // attempt to resolve it..
          IChunkType chunkType =
              encodedChunk.getModel().getDeclarativeModule().getChunkType(kind).get();

          Object kindValue = kind;
          if (chunkType != null) {
            if (LOGGER.isDebugEnabled())
              LOGGER.debug("Got chunktype " + chunkType + " for " + kind);
            kindValue = chunkType;
          } else if (LOGGER.isDebugEnabled())
            LOGGER.debug("No chunktype matching " + kind + " could be found, using string value");

          if (kindMatchesPattern(originalSearchRequest, kindValue)) {
            mutableRequest.addSlot(new BasicSlot(IAuralModule.KIND_SLOT, kindValue));
            return;
          }
        } catch (Exception e) {
          throw new RuntimeException("Failed to get kind ", e);
        }
  }
  @Override
  protected boolean removeSourceChunkInternal(IChunk chunkToRemove) {
    if (LOGGER.isDebugEnabled())
      LOGGER.debug("attempting to remove " + chunkToRemove + " from " + getName());

    if (_times.containsKey(chunkToRemove)) {
      if (LOGGER.isDebugEnabled()) LOGGER.debug("removing and setting status slots");

      double time = _times.remove(chunkToRemove);
      _sourceChunks.remove(time);

      chunkRemoved(chunkToRemove);

      if (LOGGER.isDebugEnabled()) {
        // TODO remove debugging code
        LOGGER.debug(getName() + " Source Chunks & Times " + _sourceChunks);
        for (IChunk chunk : _sourceChunks.values())
          if (chunk.isEncoded()) LOGGER.debug("WARNING : " + chunk + " has already been encoded");
      }

      return true;
    } else
      /*
       * TODO remove debugging code safety check while I debug this issue: in
       * some cases, the chunk (in the buffer) is being encoded and merged with
       * an existing chunk - now, the buffer should not contain any encoded
       * chunks, but somehow this one is still in here.. the problem is that the
       * merging process changes the hashcode which will mean that the above
       * check will fail.. this finds the problem and throws the appropriate
       * exception so we can stop the execution
       */
      /*
       * problem found: two buffers, with the same chunk, one removes and
       * encodes. solution: make all insertions copies
       */
      for (IChunk source : _times.keySet())
        if (source.equals(chunkToRemove))
          throw new IllegalStateException(
              "Mayday, hashcode has changed for encoded chunk " + chunkToRemove);

    if (LOGGER.isDebugEnabled()) LOGGER.debug("nothing to remove");
    return false;
  }
  /**
   * must only be called within the write lock. will remove chunks until capacity is no longer
   * reached (i.e. there is room for one more chunk) - this is called by addSourceChunkInternal
   */
  private void ensureCapacity() {
    IModel model = getModel();
    IMessageBuilder sb = null;
    while (isCapacityReached()) {
      if (sb == null) sb = Logger.messageBuilder();
      else sb.clear();

      /*
       * remove the first..
       */
      IChunk toRemove = getRemovalCandidate();
      if (LOGGER.isDebugEnabled() || Logger.hasLoggers(model)) {
        sb.append(toRemove.toString());
        sb.append(" is being removed because capacity has been reached");
        String msg = sb.toString();

        if (LOGGER.isDebugEnabled()) LOGGER.debug(msg);
        if (Logger.hasLoggers(model)) Logger.log(model, Logger.Stream.BUFFER, msg);
      }
      removeSourceChunk(toRemove);
    }

    if (sb != null) MessageBuilderFactory.recycle(sb);
  }
  /** when a chunk is matched against, we modify its insertion time.. */
  @Override
  protected boolean matchedInternal(IChunk chunk) {

    if (!_times.containsKey(chunk)) {
      if (LOGGER.isWarnEnabled()) LOGGER.warn(chunk + " was matched, but is not in the buffer?");
      return false;
    }

    /*
     * if LRA, we've done all we need to
     */
    EjectionPolicy policy = getEjectionPolicy();

    if (policy == EjectionPolicy.LeastRecentlyAdded || policy == EjectionPolicy.MostRecentlyAdded)
      return true;

    /*
     * now we can tweak the access time, but only if the policy is LRU or LRM
     */
    double oldTime = _times.get(chunk);
    double newTime = ACTRRuntime.getRuntime().getClock(getModel()).getTime();

    _sourceChunks.remove(oldTime);
    /*
     * make sure there are no collisions
     */
    while (_sourceChunks.containsKey(newTime) && !chunk.equals(_sourceChunks.get(newTime)))
      /*
       * problem of more than one chunk inserted at the same time (could happen
       * during path-integration)
       */
      newTime += 0.000001;

    _times.put(chunk, newTime);
    _sourceChunks.put(newTime, chunk);

    if (LOGGER.isDebugEnabled())
      LOGGER.debug(getName() + " Source Chunks & Times " + _sourceChunks);
    return true;
  }
  @Override
  protected IChunk addSourceChunkInternal(IChunk chunkToInsert) {
    if (LOGGER.isDebugEnabled()) LOGGER.debug("attempting to insert " + chunkToInsert);

    /*
     * ok, something will be changing..
     */
    IChunk errorChunk = getErrorChunk();

    /*
     * did something go wrong? set the states..
     */
    if (errorChunk.equals(chunkToInsert)
        || !isValidChunkType(chunkToInsert.getSymbolicChunk().getChunkType())) {
      if (LOGGER.isDebugEnabled())
        LOGGER.debug(getName() + " : " + chunkToInsert + " was error or invalid of chunk type");
      setStateChunk(errorChunk);
      chunkToInsert = null;
    }

    /*
     * all is good, let's set the chunk
     */
    if (chunkToInsert != null) {
      /*
       * are we bumping up against the maximum capacity?
       */
      ensureCapacity();

      double now = ACTRRuntime.getRuntime().getClock(getModel()).getTime();

      double time = Double.MIN_VALUE;

      /*
       * if LRA or LRU, time will be now, if modified, we set it as minimum
       * double value (can't be negative inf because of potential value
       * collisions, see below)
       */
      switch (getEjectionPolicy()) {
        case LeastRecentlyAdded:
        case LeastRecentlyUsed:
        case MostRecentlyAdded:
        case MostRecentlyUsed:
          time = now;
          break;
      }

      /*
       * problem of more than one chunk inserted at the same time (could happen
       * if a production fires multiple adds)
       */
      while (_sourceChunks.containsKey(time) && !chunkToInsert.equals(_sourceChunks.get(time)))
        time += 0.0000001;

      _sourceChunks.put(time, chunkToInsert);
      _times.put(chunkToInsert, time);

      if (LOGGER.isDebugEnabled())
        LOGGER.debug(getName() + " Source Chunks & Times " + _sourceChunks);

      IModel model = getModel();
      if (LOGGER.isDebugEnabled() || Logger.hasLoggers(model)) {
        IMessageBuilder sb = Logger.messageBuilder();
        sb.append(getName())
            .append(" inserted ")
            .append(chunkToInsert.getSymbolicChunk().getName());

        if (LOGGER.isDebugEnabled()) LOGGER.debug(sb.toString());

        Logger.log(model, Logger.Stream.BUFFER, sb);
      }

      chunkInserted(chunkToInsert);
    }

    return chunkToInsert;
  }
Exemple #8
0
  /**
   * handles the updating of associative links, references times, and context/needed tallies. should
   * also handle similarities, but that is not implemented yet and will be by the six version of
   * this.<br>
   * The updating is done here since the listener is removed after encoding, so the master chunk
   * will not have this listener attached
   *
   * @param event
   * @see
   *     org.jactr.core.chunk.event.ChunkListenerAdaptor#mergingInto(org.jactr.core.chunk.event.ChunkEvent)
   */
  @Override
  public void mergingInto(ChunkEvent event) {
    IChunk self = event.getSource();
    IChunk master = event.getChunk();

    ISubsymbolicChunk4 selfSSC = (ISubsymbolicChunk4) self.getSubsymbolicChunk();
    ISubsymbolicChunk4 masterSSC = (ISubsymbolicChunk4) master.getSubsymbolicChunk();

    // update the references for master
    masterSSC.accessed(event.getSimulationTime());

    masterSSC.setTimesInContext(masterSSC.getTimesInContext() + selfSSC.getTimesInContext());
    masterSSC.setTimesNeeded(masterSSC.getTimesNeeded() + selfSSC.getTimesNeeded());

    /*
     * and refs
     */
    IReferences refs = masterSSC.getReferences();
    for (double refTime : selfSSC.getReferences().getTimes()) refs.addReferenceTime(refTime);

    // will allocate
    Collection<Link> links = selfSSC.getIAssociations(null);

    for (Link iLink : links) {
      IChunk iChunk = iLink.getIChunk();
      Link masterLink = masterSSC.getIAssociation(iChunk);
      if (masterLink != null) {
        /** need to merge the links */
        if (LOGGER.isDebugEnabled())
          LOGGER.debug(master + " already linked to " + iChunk + ", merging");
        masterLink.setCount(Math.max(masterLink.getCount(), iLink.getCount()));
        masterLink.setStrength(Math.max(masterLink.getStrength(), iLink.getStrength()));
      } else {
        /** add the link to master */
        if (LOGGER.isDebugEnabled())
          LOGGER.debug(master + " not already linked to " + iChunk + ", linking.");
        Link newLink = new Link(master, iChunk, iLink.getCount(), iLink.getStrength());
        masterSSC.addLink(newLink);
        ((ISubsymbolicChunk4) iChunk.getSubsymbolicChunk()).addLink(newLink);
      }

      /*
       * reduce the count so that we are sure we're removing the link
       */
      iLink.setCount(1);
      selfSSC.removeLink(iLink);
      ((ISubsymbolicChunk4) iChunk.getSubsymbolicChunk()).removeLink(iLink);
    }

    links.clear();
    links = selfSSC.getJAssociations(links);

    for (Link jLink : links) {
      IChunk jChunk = jLink.getJChunk();
      Link masterLink = masterSSC.getIAssociation(jChunk);
      if (masterLink != null) {
        /** need to merge the links */
        if (LOGGER.isDebugEnabled())
          LOGGER.debug(jChunk + " already linked to " + master + ", merging");
        masterLink.setCount(Math.max(masterLink.getCount(), jLink.getCount()));
        masterLink.setStrength(Math.max(masterLink.getStrength(), jLink.getStrength()));

      } else {
        /** add the link to master */
        if (LOGGER.isDebugEnabled())
          LOGGER.debug(jChunk + " not already linked to " + master + ", linking.");
        Link newLink = new Link(jChunk, master, jLink.getCount(), jLink.getStrength());
        masterSSC.addLink(newLink);
        ((ISubsymbolicChunk4) jChunk.getSubsymbolicChunk()).addLink(newLink);
      }

      /*
       * reduce the count so that we are sure we're removing the link
       */
      jLink.setCount(1);
      selfSSC.removeLink(jLink);
      ((ISubsymbolicChunk4) jChunk.getSubsymbolicChunk()).removeLink(jLink);
    }
  }
Exemple #9
0
  @Override
  public void slotChanged(ChunkEvent ce) {
    IChunk iChunk = ce.getSource();
    Object oldValue = ce.getOldSlotValue();
    Object newValue = ce.getNewSlotValue();

    if (LOGGER.isDebugEnabled())
      LOGGER.debug(iChunk + "." + ce.getSlotName() + "=" + newValue + " (was " + oldValue + ")");

    /*
     * we can only do this if ISubsymbolicChunk is ISubsymbolicChunk4
     */
    if (!(iChunk.getSubsymbolicChunk() instanceof ISubsymbolicChunk4)) {
      if (LOGGER.isWarnEnabled())
        LOGGER.warn(
            "Can only adjust associative links if the chunk's subsymbolic is derived from ISubsymbolicChunk4");
      return;
    }

    /*
     * I chunk is the owner that references J
     */
    ISubsymbolicChunk4 sscI = (ISubsymbolicChunk4) iChunk.getSubsymbolicChunk();

    /*
     * first the old chunk value..
     */
    if (oldValue instanceof IChunk) {
      IChunk jChunk = (IChunk) oldValue;
      if (jChunk.getSubsymbolicChunk() instanceof ISubsymbolicChunk4) {
        ISubsymbolicChunk4 sscJ = (ISubsymbolicChunk4) jChunk.getSubsymbolicChunk();

        Link sJI = sscJ.getIAssociation(iChunk);

        if (sJI != null) {
          sJI.decrement();
          if (sJI.getCount() == 0) {
            if (LOGGER.isDebugEnabled())
              LOGGER.debug("Removing link between " + iChunk + " and " + jChunk + " : " + sJI);
            sscI.removeLink(sJI);
            sscJ.removeLink(sJI);
          } else if (LOGGER.isDebugEnabled())
            LOGGER.debug(
                "Multiple links established between "
                    + iChunk
                    + " and "
                    + jChunk
                    + " decrementing : "
                    + sJI);
        }
      } else if (LOGGER.isWarnEnabled())
        LOGGER.warn(
            "old value " + jChunk + " doesn't have a ISubsymbolicChunk4, nothing to be done");
    }

    /*
     * now for the new one
     */
    if (newValue instanceof IChunk) {
      IChunk jChunk = (IChunk) newValue;
      if (jChunk.getSubsymbolicChunk() instanceof ISubsymbolicChunk4) {
        ISubsymbolicChunk4 sscJ = (ISubsymbolicChunk4) jChunk.getSubsymbolicChunk();

        Link sJI = sscJ.getIAssociation(iChunk);
        /*
         * is this a new linkage?
         */
        if (sJI == null) {
          sJI = new Link(jChunk, iChunk);
          if (LOGGER.isDebugEnabled())
            LOGGER.debug("Adding link between " + iChunk + " and " + jChunk + " : " + sJI);
          sscI.addLink(sJI);
          sscJ.addLink(sJI);
        } else {
          sJI.increment(); // not new, but we need to increment the link
          if (LOGGER.isDebugEnabled())
            LOGGER.debug(
                "Link already established between "
                    + iChunk
                    + " and "
                    + jChunk
                    + " incrementing : "
                    + sJI);
        }
      } else if (LOGGER.isWarnEnabled())
        LOGGER.warn(
            "new value " + jChunk + " doesn't have a ISubsymbolicChunk4, nothing to be done");
    }
  }
  public void copy(IChunk source, IChunk destination) {
    for (String key : source.getMetaDataKeys())
      destination.setMetaData(key, source.getMetaData(key));

    destination.setMetaData(COPIED_FROM_KEY, source);
  }
 public void dispose(IChunk chunk) {
   chunk.dispose();
 }