Package heart

Source Code of heart.WorkingMemory$AVEntry

/**
*
*     Copyright 2013-15 by Szymon Bobek, Grzegorz J. Nalepa, Mateusz Ślażyński
*
*
*     This file is part of HeaRTDroid.
*     HeaRTDroid is a rule engine that is based on HeaRT inference engine,
*     XTT2 representation and other concepts developed within the HeKatE project .
*
*     HeaRTDroid is free software: you can redistribute it and/or modify
*     it under the terms of the GNU General Public License as published by
*     the Free Software Foundation, either version 3 of the License, or
*     (at your option) any later version.
*
*     HeaRTDroid 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 General Public License for more details.
*
*     You should have received a copy of the GNU General Public License
*     along with HeaRTDroid.  If not, see <http://www.gnu.org/licenses/>.
*
**/


package heart;

import heart.alsvfd.Null;
import heart.alsvfd.SimpleNumeric;
import heart.alsvfd.SimpleSymbolic;
import heart.alsvfd.Value;
import heart.exceptions.AttributeNotRegisteredException;
import heart.exceptions.NotInTheDomainException;
import heart.xtt.Attribute;
import heart.xtt.Type;
import heart.xtt.XTTModel;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map.Entry;

/**
*
* @author sbk
*
* This is the class that is responsible for state management of the system
* Every attributes values changes has to be done with this class methods.
* It also gives access to the current and past system states.
*
*/
public class WorkingMemory {
 
  /**
   * The list of attributes names and real attributes and their values that are matched against the names.
   * In usual case this will be redundant, but allows faster search thanks to HashMap.
   */
  private HashMap<String, AVEntry> registeredAttributes;
 
  /**
   * The list of states of the system. The resolution of how often the system state is logged is set
   * by the flag.
   */
  private LinkedList<State> historyLog;
 
  /**
   * The list of snapshots of the system state. This is different from the {@link #historyLog} as it allows custom names,
   * and can be invoked by the user on demand.
   */
  private HashMap<String,State> snapshots;
 
  /**
   * Default constructor for the working memory object.
   */
  public WorkingMemory() {
    registeredAttributes = new HashMap<String, AVEntry>();
    historyLog = new LinkedList<State>();
    snapshots = new HashMap<String, State>();
  }
 
  /**
   * The method sets values of the attributes defined by state parameter.
   * Depending on the autoregister parameter, the system registers all the attributes
   * from the model.
   *
   * @param state a state to be set
   * @param model the model from which the attributes values re to be set
   * @param autoregister the parameter indicating if the method should register all the attributes from the model (if true) or none (if false).
   * @throws NotInTheDomainException
   * @throws AttributeNotRegisteredException
   */
  public void setCurrentState(State state, XTTModel model, boolean autoregister) throws NotInTheDomainException, AttributeNotRegisteredException{
    for(StateElement se : state){
      Attribute attr = model.getAttributeByName(se.getAttributeName());
      setAttributeValue(attr, se.getValue(), autoregister);
    }
  }
 
  /**
   * The method returns values of all registered attributes in a form of {@link State} object.
   *
   * @return the state that contains values of all registered attributes.
   *
   */
  public State getCurrentState(){
    State current = new State();
    for(Entry<String, AVEntry> se : registeredAttributes.entrySet()){
      current.addStateElement(new StateElement(se.getKey(),se.getValue().getValue()));
    }
    return current;
  }
 
  /**
   * Returns the state of the system only for the registered attributes within the model
   *
   * @param model a model which attributes should be returned as a state
   * @return the current state of the attributes values from the model given as a parameter
   */
  public State getCurrentState(XTTModel model){
    State current = new State();
    for(Attribute a: model.getAttributes()){
      Value  v = getAttributeValue(a);
      current.addStateElement(new StateElement(a.getName(),v));
    }
   
    return current;
  }
 
  /**
   * It registers the attribute that later will be accessible and will be included in snapshots and current state.
   * Registering and unregistering is based on attributes names, not object refferences.
   *
   * @param attribute an attribute to be registered
   */
  public void registerAttribute(Attribute attribute){
    try {
      registeredAttributes.put(attribute.getName(), new AVEntry(attribute, new Null()));
    } catch (NotInTheDomainException e) {
      // This will not happend, as the Null ca always be assigned as an attribute value
    }
  }
 
  /**
   * It registers the attribute that later will be accessible and will be included in snapshots and current state.
   * Registering and unregistering is based on attributes names, not object refferences.
   *
   * @param name a name of the attribute to register
   * @param model a model where the attribute is located
   */
  public void registerAttribute(String name, XTTModel model){
    Attribute attr = model.getAttributeByName(name);
    registerAttribute(attr);
  }
 
  /**
   * It registers all attributes from a given model
   * Registering and unregistering is based on attributes names, not object refferences.
   *
   * @param model a model from which the attributes have to be regisered
   */
  public void registerAllAttributes(XTTModel model){
    for(Attribute a: model.getAttributes()){
      registerAttribute(a);
    }
  }
 
  /**
   * It unregisters the attribute of a given name.
   * If such attribute is no present in the register, nothing happens.
   * Registering and unregistering is based on attributes names, not object refferences.
   *
   * @param name a name of the attribute to unregister
   */
  public void unregisterAttribute(String name){
    registeredAttributes.remove(name);
  }
 
  /**
   * The method unregisters all the attribute from a model given as a parameter.
   * Registering and unregistering is based on attributes names, not object refferences.
   *
   * @param model a model with attributes to unregister
   */
  public void unregisterAll(XTTModel model){
    for(Attribute a: model.getAttributes()){
      unregisterAttribute(a.getName());
    }
  }

  /**
   * The method return a value of an attribute of a given name.
   * If the attribute is not registered, {@link Null} is returned.
   *
   * @param attributeName the attribute name which value is needed
   * @return the value of the attribute or {@link Null} id the attribute is not registered
   */
  public Value getAttributeValue(String attributeName){
    AVEntry ave = registeredAttributes.get(attributeName);
    if(ave != null){
      return ave.getValue();
    }else{
      return new Null();
    }
  }
 
  /**
   * The method return a value of an attribute of a given name.
   * If the attribute is not registered, {@link Null} is returned.
   *
   * @param attr the attribute which value is needed
   * @return the value of the attribute or Null if it is not registered
   */
  public Value getAttributeValue(Attribute attr){
    AVEntry ave = registeredAttributes.get(attr.getName());
    if(ave != null){
      return ave.getValue();
    }else{
      return new Null();
    }
  }
 
  /**
   * The method sets a given value to the attribute which name is passed as a parameter.
   * It the attribute is not present in the WorkingMemmory registry, the {@link AttributeNotRegisteredException} is thrown.
   *
   * @param attributeName name of the attribute which value has to be set
   * @param value the value to set
   * @throws AttributeNotRegisteredException
   * @throws NotInTheDomainException
   */
  public void setAttributeValue(String attributeName, Value value) throws AttributeNotRegisteredException, NotInTheDomainException{
    AVEntry ave = registeredAttributes.get(attributeName);
    if(ave != null){
      ave.setAttributeValue(value);
    }else{
      throw new AttributeNotRegisteredException("Attribute "+attributeName+" was not registered.", attributeName);
    }
  }
 
  /**
   * The method sets a given value to the attribute which name is passed as a parameter.
   * It the attribute is not present in the WorkingMemmory registry, the {@link AttributeNotRegisteredException} is thrown.
   *
   * @param attributeName name of the attribute which value has to be set
   * @param value the value to set
   * @throws AttributeNotRegisteredException
   * @throws NotInTheDomainException
   */
 
  /**
   * The method sets a given value to the attribute which name is passed as a parameter.
   * It the attribute is not present in the WorkingMemmory registry, the {@link AttributeNotRegisteredException} is thrown.
   *
   * @param attributeName a name of the attribute
   * @param model a model in which the attribute is present
   * @param value a value to be set
   * @param autoregister true or false boolean indicating weather register the attribute in workingMemory or not.
   *
   * @throws AttributeNotRegisteredException
   * @throws NotInTheDomainException
   */
  public void setAttributeValue(String attributeName, XTTModel model, Value value, boolean autoregister) throws AttributeNotRegisteredException, NotInTheDomainException{
    AVEntry ave = null;
    if(autoregister) registerAttribute(attributeName, model);
   
    ave = registeredAttributes.get(attributeName);
    if(ave != null){
      ave.setAttributeValue(value);
    }else{
      throw new AttributeNotRegisteredException("Attribute "+attributeName+" was not registered.", attributeName);
    }
  }
 
  /**
   * The method sets a given value to the attribute which  is passed as a parameter.
   * It the attribute is not present in the WorkingMemmory registry, the {@link AttributeNotRegisteredException} is thrown in case
   * when autoregister is set to false. In case when autoregister is set to true, the Attribute will be automatically
   * registered in Working Memory registry.
   *
   * @param attribute the attribute which value has to be set
   * @param value the value to set
   * @param autoregister the parameter indicating if the method should register the attribute (if true) or none (if false).
   * @throws AttributeNotRegisteredException
   * @throws NotInTheDomainException
   */
  public void setAttributeValue(Attribute attribute, Value value, boolean autoregister) throws AttributeNotRegisteredException, NotInTheDomainException{
    if(autoregister) registerAttribute(attribute);
    AVEntry ave = registeredAttributes.get(attribute.getName());
    ave.setAttributeValue(value);
  }
 
  /**
   * The method makes a snapshot of a current system state, by saving all the values of the registered attributes.
   *
   * @param snapshotName the name of the snapshot.
   */
  public void makeSnapshot(String snapshotName){
    State snapshot = getCurrentState();
    snapshot.setName(snapshotName);
    //TODO: what if the snapshot of a given name exists?
    snapshots.put(snapshotName, snapshot);
  }
 
  /**
   * It returns the state that represents the snapshot of a given name.
   *
   * @param snapshotName a name of the snapshot to return
   * @return a state representing the snapshot or null if the snapshot of a given name is not present
   */
  public State getSnapshot(String snapshotName){
    return snapshots.get(snapshotName);
  }
 
  /**
   * It saves the state of the system at the time of the method is being call
   * to the history log. It differs from the {@link #makeSnapshot(String)} method
   * as the logs are more anonymous, as they cannot have custom names, and what is more
   * logs may be recorded automatically be the logging mechanism, whereas snapshots
   * can only be made by the programmer explicitly with the {@link #makeSnapshot(String)} call.
   */
  public void recordLog(){
    State s = getCurrentState();
    s.setName("log_"+s.getTimestamp());
    historyLog.add(s);
  }

  /**
   * It returns the entire history log with all the records made.
   *
   * @return the list of all States made with the {@link #recordLog()} method.
   */
  public LinkedList<State> getHistoryLog() {
    return historyLog;
  }


  /**
   * The method returns list of all snapshots made with the {@link #makeSnapshot(String)}
   * method.
   *
   * @return the list of all the snapshots made.
   */
  public LinkedList<State> getSnapshots() {
    return new LinkedList<State>(snapshots.values());
  }


  protected class AVEntry{
    /**
     * The attribute which value is stored within the entry
     */
    private Attribute attr;
   
    /**
     * current value of the Attribute. This is where the current state is stored
     */
    private Value value;
   
    public AVEntry(Attribute attr, Value value) throws NotInTheDomainException{
      this.attr = attr;
      setAttributeValue(value);
    }
   
    protected Attribute getAttribute(){
      return attr;
    }
   
    protected Value getValue(){
      return value;
    }
   
    /**
     * A method that sets a value of the attribute for a value given as a parameter.
     * The method checks if the value that is to be assigned is in a domain of the
     * attribute type. If not, the {@link NotInTheDomainException} is thrown.
     *
     * Casting between {@link SimpleSymbolic} and {@link SimpleNumeric} is allowed if
     * SimpleSimbolic type is ordered. In every other case, the {@link NotInTheDomainException}
     * is thrown.
     *
     * The only exception is {@link Null} value, that despite not being in any domain
     * can be assigned to the attribute value.
     *
     * @param value to set
     * @throws NotInTheDomainException
     */
    protected void setAttributeValue(Value value) throws NotInTheDomainException {
      if(value instanceof Null){
        this.value = value;
      }else if(value.isInTheDomain(attr.getType())){
        if(attr.getXTTClass().equals(Attribute.CLASS_SIMPLE)){
          if(value instanceof SimpleNumeric && attr.getType().getBase().endsWith(Type.BASE_SYMBOLIC)){
            // Add casting between symbolic and numeric if ordered
            this.value = SimpleSymbolic.findInTheDomain((SimpleNumeric) value, attr.getType());
            if(this.value == null){
              throw new NotInTheDomainException(attr.getType().getDomain(), value,
                  "Setting value of attribute '"+attr.getName()+
                  "' for a value '"+value+"' that is not in the domain that is not 'Null'.");
            }
          }else if(value instanceof SimpleSymbolic && attr.getType().getBase().endsWith(Type.BASE_NUMERIC)){
            this.value = SimpleSymbolic.findInTheDomain((SimpleNumeric) value, attr.getType());
            if(this.value == null){
              throw new NotInTheDomainException(attr.getType().getDomain(), value,
                  "Setting value of attribute '"+attr.getName()+
                  "' for a value '"+value+"' that is not in the domain that is not 'Null'.");
            }
          }else{
            this.value = value;
          }
        }else if(attr.getXTTClass().equals(Attribute.CLASS_GENERAL)){
          this.value = value;
        }
      }else{
        throw new NotInTheDomainException(attr.getType().getDomain(), value,
            "Setting value of attribute '"+attr.getName()+
            "' for a value '"+value+"' that is not in the domain that is not 'Null'.");
      }
    }
  }
 
 
 
 
 
 
}
TOP

Related Classes of heart.WorkingMemory$AVEntry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.