This is an archived abbreviated version of jennsand.com. Information here is only kept for historical purposes.

Masters thesis code: Appraisal of Choices

Go to thesis code page for an explanation of how this code fits into the overall theory or go to the thesis overview page for information on the entire thesis. This code is written for the JACK programming language (which has a Java base) available through AOS.

This plan allows the agent choose which plan to try based on somatic markers (SM) (and, if required, user-defined, domain dependent in-depth reasoning). Somatic markers have already been attached to each plan, similarly to a preference value, ie how much you would like to do each specific plan.

AppraisalOfChoices.plan

package character;

import character.generic.Activities; 
import character.generic.Cope; 
import character.generic.EmotionFocusedCopingGoal; 
import character.generic.Facts; 
import character.generic.InteractionRequest; 
import character.generic.ProblemFocusedCopingGoal; 
import character.generic.ReactiveEventResponse; 
import character.generic.SMAgent; 
import character.generic.SomaticMarkers; 
import character.generic.classes.PlanGoal; 
import character.generic.classes.PosNegVal; 
import character.generic.classes.SomaticMarkerHandler; 
import character.generic.goalPlanHierarchy.GoalPlanHierarchy; 
import java.lang.Math; 
import java.util.Random; 
import java.util.Vector;

/** This plan allows the agent choose which plan to try based on
 somatic markers (SM) (and, if required, user-defined, domain dependent
 in-depth reasoning).
 Somatic markers have already been attached to each plan, similarly
 to a preference value, ie how much you would like to do each specific plan.
*/ 
public plan AppraisalOfCoping extends Plan {

    #chooses for event Cope;
    #chooses for event ProblemFocusedCopingGoal;
    #chooses for event EmotionFocusedCopingGoal;
    //A simple program is run to automatically add other domain-dependent plans
    //  that will use this plan to make decisions.
    public static double HIGH_PROB_CUTOFF = 1;
    public static double MED_PROB_CUTOFF = 0.4;
    public static double LOW_PROB_CUTOFF = 0.1;
    #handles event PlanChoice pce;
    #sends event ReactiveEventResponse irResponse;
    #reads data Facts facts;
    #uses data SomaticMarkers somaticMarkers;
    #uses data GoalPlanHierarchy goalPlanHierarchy;
    #uses data Activities activities;
    
    #reasoning method
    body()
    {
        // Set the marker in the agent so that we know we used this plan.
        ((SMAgent) getAgent()).usedPlanChoiceMetaPlan = true;
       
        // These vectors will hold the possible choices into three groups.
        //  The first group contains choices that are highly desirable
        Vector pleaseChoose = new Vector();
        //  The second group contains choices that you're not sure about
        Vector dontCare = new Vector();
        //  The third group contains choices that you don't want to choose.
        Vector dontChoose = new Vector();        
        
        // Create sum variables so can determine average SM value
        double sumOfSMs = 0;
        double sum_squared = 0;
        double numOfPlans = 0;
        
        Signature s;
        int activityID = -1;
        int count = 0;
        
        // Loop through all the plans that we need to choose from, the instances.
        // These must be plans that say to use this plan to decide between them,
        //  i.e. "SomaticMarkerHandler" plans.
        // Start by finding the mean and standard deviation of the somatic marker values
        for ( s = pce.applicable.first();
                s !=null;
                s = pce.applicable.next(s)
             )
        {
            if ( s.getInfo() instanceof SomaticMarkerHandler )
            {
                // This is the sort of plans we care about
                SomaticMarkerHandler smh = (SomaticMarkerHandler) s.getInfo();
                // Grab the activity ID
                activityID = smh.activityID;
                
                // Find somatic marker value
                double currSM = smh.somaticMarkerValue;
                // Add this value to the sum
                sumOfSMs += currSM;
                sum_squared += currSM*currSM;
                // Add one more to the count of plans found
                numOfPlans += 1.0;
                
            }
        }
        
        // Now work out the average (mean) SM value for all these applicable plans
        double newAvSM = sumOfSMs/numOfPlans; 
        activities.setAvSM(activityID, newAvSM);
        
        // Now work out the standard deviation
        double sigma = Math.sqrt(sum_squared/numOfPlans - newAvSM*newAvSM);
        
        // Therefore the cutoffs are going to be..
        // Work out cutoff levels for these groups
        PosNegVal desirableRange = ((SMAgent) getAgent()).eality.getDesirableRange();
        double highCutOff = newAvSM+desirableRange.pos*sigma;
        double lowCutOff = newAvSM-desirableRange.neg*sigma; // Must be a negative value
        
        // Now loop back through the plans and group them based on the cutoffs
        // Loop through all instances found
        for ( s = pce.applicable.first();
                s !=null;
                s = pce.applicable.next(s)
             )
        {
            if ( s.getInfo() instanceof SomaticMarkerHandler )
            {
                //System.out.println("This should be a somaticMarkerHandler type");
                // This is about the sort of plans we care about
                SomaticMarkerHandler smh = (SomaticMarkerHandler) s.getInfo();
                // Grab the activity ID
                activityID = smh.activityID;
                                
                // Find somatic marker value
                double currSM = smh.somaticMarkerValue;
                
                // Based on value group into three groups
                if ( currSM > highCutOff ) {
                    // This is a highly desirable plan
                    pleaseChoose.add(s);    // Add signature, not the somaticMarkerHandler
                }
                else if ( currSM < lowCutOff ) {
                    // This has a low somatic marker, don't choose this if possible
                    dontChoose.add(s);
                }
                else {
                    // Don't know whether this plan is "good" or "bad" yet
                    dontCare.add(s);
                }               
            }
        }
        
        
        // DOMAIN DEPENDENT: Do in-depth reasoning of which plan to choose
        //  from the groups.
        /**
         * Domain dep code here if required...
         */
        
        // OR do a RANDOM choice from the within a group
        // First we need to order the groups...
        // Start by getting a random number [0,1)
        double epsilon = ((SMAgent) getAgent()).ranGenerator.nextDouble();
        Vector firstGroup, secondGroup, thirdGroup;
        if ( epsilon <= LOW_PROB_CUTOFF ) { // Unlikely to happen
            System.out.println("Going to try to choose from worst group first, "+epsilon);
            // If this random number is below the bottom cut off we'll try choosing
            //  from the dontChoose group
            firstGroup = dontChoose;
            // If that doesn't work, we need to set the dontCare group as our next choice
            secondGroup = dontCare;
            // If that doesn't work, we need to set the pleaseChoose group as our final choice 
            thirdGroup = pleaseChoose;
        }
        else if ( epsilon <= MED_PROB_CUTOFF ) { // Mildly likely to happen
            System.out.println("Going to try to choose from middle group first, "+epsilon);
            // If this random number is below the middle cut off we'll try choosing
            //  from the dontCare group
            firstGroup = dontCare;
            // If that doesn't work, we need to set the pleaseChoose group as our next choice
            secondGroup = pleaseChoose;
            // If that doesn't work, we need to set the  dontChoose group as our final choice 
            thirdGroup = dontChoose;
        }
        else {  // Most likely to happen
            System.out.println("Going to try to choose from best group first, "+epsilon);
            // Must be a large number, try to choose from the pleaseChoose group
            firstGroup = pleaseChoose;
            // If that doesn't work, we need to set the  dontCare group as our next choice
            secondGroup = dontCare;
            // If that doesn't work, we need to set the dontChoose group as our final choice 
            thirdGroup = dontChoose;
        }
        
        // Choose a plan at random from the first group in their new order
        if ( firstGroup.size() > 0 ) {
            // There are some choices available in the first group
            int nextChoice = ((SMAgent) getAgent()).ranGenerator.nextInt(firstGroup.size());
            pce.chosen = (Signature) firstGroup.elementAt(nextChoice);  
            SomaticMarkerHandler tempsmh = (SomaticMarkerHandler) pce.chosen.getInfo();
        }
        // If there are no plans in the first group...
        // Try the second group
        else if ( secondGroup.size() > 0 ) {
            // Couldn't choose a plan from our preferred group, choose one from the next group
            int nextChoice = ((SMAgent) getAgent()).ranGenerator.nextInt(secondGroup.size());
            pce.chosen = (Signature) secondGroup.elementAt(nextChoice);  
            SomaticMarkerHandler tempsmh = (SomaticMarkerHandler) pce.chosen.getInfo();
        }
        // If there are no plans in the second group....
        // Try the third group
        else if ( thirdGroup.size() > 0 ) {
            // There are plans left in our preferred groups so choose from final group.
            int nextChoice = ((SMAgent) getAgent()).ranGenerator.nextInt(thirdGroup.size());
            pce.chosen = (Signature) thirdGroup.elementAt(nextChoice);  
            SomaticMarkerHandler tempsmh = (SomaticMarkerHandler) pce.chosen.getInfo();
        }
        else {  // This means there are no applicable plans of the type
               // SomaticMarkerHandler.  Just choose first plan
            pce.chosen = pce.applicable.first();
        }
        
        return true;
      
    }
    
}