package seg.jUCMNav.strategies;

import grl.Actor;
import grl.Contribution;
import grl.Decomposition;
import grl.DecompositionType;
import grl.Dependency;
import grl.ElementLink;
import grl.Evaluation;
import grl.EvaluationStrategy;
import grl.IntentionalElement;
import grl.QualitativeLabel;
import grl.kpimodel.KPIEvalValueSet;
import grl.kpimodel.QualitativeMapping;
import grl.kpimodel.QualitativeMappings;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import fm.MandatoryFMLink;
import fm.OptionalFMLink;
import seg.jUCMNav.extensionpoints.IGRLStrategyAlgorithm;
import seg.jUCMNav.model.util.MetadataHelper;
import seg.jUCMNav.model.util.StrategyEvaluationRangeHelper;
import seg.jUCMNav.views.preferences.StrategyEvaluationPreferences;
import urn.URNspec;
import urncore.Metadata;

/**
 * This class implements the quantitative GRL evaluation algorithm.
 * 
 * @author sghanava, gunterm
 * 
 */
public class QuantitativeGRLStrategyAlgorithm extends PropagationGRLStrategyAlgorithm implements IGRLStrategyAlgorithm {
	
	/**
     * Metadata name used to store run-time aggregate evaluations
     */
    public static final String METADATA_AGGREVAL = "_aggrEval"; //$NON-NLS-1$
    public static final String METADATA_ADDAGGR = "_addAggregate"; //$NON-NLS-1$
    public static final String METADATA_DATAQUALITY = "_dataqual"; //$NON-NLS-1$
    public static int decopConfValue = 0; 
    public static int contConfValue = 0;   
    public static int contConfValuePrevious = 0;  
    public static int contCounter = 0; 
    int minRange;
    
    /*
     * (non-Javadoc)
     * 
     * @see seg.jUCMNav.extensionpoints.IGRLStrategiesAlgorithm#init(java.util.Vector)
     */
    public void init(EvaluationStrategy strategy, HashMap evaluations) {
        // determines whether -100 or 0 should be used as a minimum scale.
        minRange = -100 * (StrategyEvaluationRangeHelper.getCurrentRange(strategy.getGrlspec().getUrnspec()) ? 0 : 1);
        super.init(strategy, evaluations);
        
    }

    /*
     * (non-Javadoc)
     * 
     * @see seg.jUCMNav.extensionpoints.IGRLStrategiesAlgorithm#getEvaluationType()
     */
    public int getEvaluationType() {
        return IGRLStrategyAlgorithm.EVAL_QUANTITATIVE;
    }

    /*
     * (non-Javadoc)
     * 
     * @see seg.jUCMNav.extensionpoints.IGRLStrategiesAlgorithm#getEvaluation(grl.IntentionalElement)
     */
    public int getEvaluation(IntentionalElement element) {
    	
    	//get Aggregate Contribution for element if Quantitative GRL strategy selected
    	if(getEvaluationType() == IGRLStrategyAlgorithm.EVAL_QUANTITATIVE){
        	getAggregation(element);
        }  
    	
    	//get Aggregate Contribution for element from QualitativeGRLStrategyAlgorithm if Mixed GRL strategy selected
    	else if(getEvaluationType() == IGRLStrategyAlgorithm.EVAL_MIXED){
        	QualitativeGRLStrategyAlgorithm qgrl = new QualitativeGRLStrategyAlgorithm(); 
        	qgrl.getAggregation(element);
        }
    	Evaluation eval = (Evaluation) evaluations.get(element);
        Integer quickReturn = preGetEvaluation(element, eval);
        if (quickReturn != null) {
            return quickReturn.intValue();
        }
        
        int result = 0;
        int decompositionValue = -10000; 
        //int decompDQValue = 0;
        int dependencyValue = 10000;  
        //int dependDQValue = 10000; 
        int[] contributionValues = new int[100]; 
        //int [] contDQValues = new int [100]
        int contribArrayIt = 0;
        
        Iterator it = element.getLinksDest().iterator(); // Return the list of elementlink
        int sumAndDecompDQ=0;
        int nbAndDecompDQ=0; 
        int avgAndDecopDQ = 0; 
        
        while (it.hasNext()) {
            ElementLink link = (ElementLink) it.next();
            if (link instanceof Decomposition) {            	
                int returndecomvalue = evaluateDecomposition(element, decompositionValue, it, link);
                // AND
                if (element.getDecompositionType().getValue()==DecompositionType.AND){
                	// add QA value to sumAndDecompDQ;  
                	Metadata metaconf = MetadataHelper.getMetaDataObj(link.getSrc(), METADATA_DATAQUALITY); 
                     String mc = metaconf.getValue();
                    //	 decopConfValue = Integer.parseInt(mc);
                	sumAndDecompDQ = sumAndDecompDQ+ Integer.parseInt(mc);
                	nbAndDecompDQ++; 
                	
                	if (!it.hasNext()) { 
                		avgAndDecopDQ = sumAndDecompDQ/nbAndDecompDQ;  
                		//decopConfValue = avgAndDecopDQ;  
                        String cvString = Integer.toString(avgAndDecopDQ);
                       MetadataHelper.addMetaData(element.getGrlspec().getUrnspec(), element, METADATA_DATAQUALITY , cvString);
                	}
                } 
                
                //OR-XOR
                else if (element.getDecompositionType().getValue()==DecompositionType.OR) {
               	//if (returndecomvalue > decompositionValue){
                	//	decompositionValue = returndecomvalue;
                		// and replace decompDQValue with the computed DQ 
                	//	Metadata metaconf = MetadataHelper.getMetaDataObj(link.getSrc(), METADATA_DATAQUALITY); 
                 //       String mc = metaconf.getValue();
                       //	 decopConfValue = Integer.parseInt(mc);
               //    	sumAndDecompDQ = Integer.parseInt(mc); 
              //     	MetadataHelper.addMetaData(element.getGrlspec().getUrnspec(), element, METADATA_DATAQUALITY , metaconf.getValue());
              //  	} 
            //   	else { 
               	//	Metadata metaconf = MetadataHelper.getMetaDataObj(link.getSrc(), METADATA_DATAQUALITY); 
              //      String mc = metaconf.getValue();
                   //	 decopConfValue = Integer.parseInt(mc);
             //  	sumAndDecompDQ = Integer.parseInt(mc); 
            //   	MetadataHelper.addMetaData(element.getGrlspec().getUrnspec(), element, METADATA_DATAQUALITY , metaconf.getValue());
          //     	}
                //	else if (returndecomvalue == decompositionValue) { 
                	//	Metadata metaconf = MetadataHelper.getMetaDataObj(link.getSrc(), METADATA_DATAQUALITY); 
                     //   String mc = metaconf.getValue();
                       //	 decopConfValue = Integer.parseInt(mc);
                  // 	sumAndDecompDQ = sumAndDecompDQ+ Integer.parseInt(mc);
                   	
                   	
                  // 	if (!it.hasNext()) { 
                   	//	avgAndDecopDQ = sumAndDecompDQ/nbAndDecompDQ;  
                   	//	decopConfValue = avgAndDecopDQ;  
                      //     String cvString = Integer.toString(decopConfValue);
                      //    MetadataHelper.addMetaData(element.getGrlspec().getUrnspec(), element, METADATA_DATAQUALITY , cvString);
                  // 	}
                		
                	//} 
               //	nbAndDecompDQ++; 
                }
                decompositionValue = returndecomvalue;  
              
                
            } else if (link instanceof Dependency) {
                dependencyValue = evaluateDependency(dependencyValue, link);
            } else if (link instanceof Contribution) {
            	Contribution contrib = (Contribution) link;
                contribArrayIt = evaluateContribution(contributionValues, contribArrayIt, link, contrib); 
              //  if (!it.hasNext()) { 
            		//decopConfValue = avgAndDecopDQ;  
                 //   String cvString = Integer.toString(contConfValue);
              //     MetadataHelper.addMetaData(element.getGrlspec().getUrnspec(), element, METADATA_DATAQUALITY , cvString);
            //	}
            }
        }
        // compute decompDQValue average 
       // avgAndDecopDQ = sumAndDecompDQ/nbAndDecompDQ; 
        result = ensureEvaluationWithinRange(result, decompositionValue, dependencyValue, contributionValues, contribArrayIt);
        result = postGetEvaluation(element, eval, result); 
       // decopConfValue = avgAndDecopDQ;  
       // String cvString = Integer.toString(decopConfValue);
      // MetadataHelper.addMetaData(element.getGrlspec().getUrnspec(), element, METADATA_DATAQUALITY , cvString);
      decopConfValue = 0; 
       contConfValue = 0;   
       contConfValuePrevious = 0;  
        return result;
    }

    protected Integer preGetEvaluation(IntentionalElement element, Evaluation eval) {
        // return immediately if we can
        Integer result = null;

        EvaluationStrategyManager strategyManager = EvaluationStrategyManager.getInstance();
        KPIEvalValueSet set = strategyManager.getActiveKPIEvalValueSet(element);
        // has a qualitative value & a mapping, load it from there instead of looking at current value. 
        if (set.getKpiConv() instanceof QualitativeMappings && set.getQualitativeEvaluationValue()!=null && set.getQualitativeEvaluationValue().length()>0 &&  element.getGrlspec()!=null)
        {
            QualitativeMappings mappings = (QualitativeMappings) set.getKpiConv();
            boolean found = false;
            for (Iterator iterator = mappings.getMapping().iterator(); iterator.hasNext();) {
                QualitativeMapping map = (QualitativeMapping) iterator.next();
                if (set.getQualitativeEvaluationValue().equalsIgnoreCase(map.getRealWorldLabel()))
                {
                    // load the evaluationValue from the conversion. 
                    result = map.getEvaluation(); 
                    eval.setQualitativeEvaluation(map.getQualitativeEvaluation());
                    found = true;
                }
            }
            if (!found) { 
                result = EvaluationStrategyManager.getQuantitativeValueForQualitativeEvaluation(QualitativeLabel.UNKNOWN_LITERAL, element.getGrlspec().getUrnspec(), 0);
                eval.setQualitativeEvaluation(QualitativeLabel.UNKNOWN_LITERAL);
            }
        }
        else  if (element.getLinksDest().size() == 0 || eval.getIntElement() != null) {
            result = eval.getEvaluation();
        }
        
        return result;
    }

    protected int postGetEvaluation(IntentionalElement element, Evaluation eval, int result) {
        // nothing in default implementation.
        return result;
    }

    protected int ensureEvaluationWithinRange(int result, int decompositionValue, int dependencyValue, int[] contributionValues, int contribArrayIt) {
        if (decompositionValue >= minRange) {
            result = decompositionValue;
        }
        if (contribArrayIt > 0) {
            boolean hasSatisfy = (result == 100);
            boolean hasDeny = (result == minRange);
            int contribValue = 0;

            for (int i = 0; i < contribArrayIt; i++) {
                if (contributionValues[i] == 100)
                    hasSatisfy = true;
                if (contributionValues[i] == minRange)
                    hasDeny = true;
                contribValue += contributionValues[i];
            }
            result = result + contribValue;

            if (result > 100) {
                result = 100;
            } else if (result < minRange) {
                result = minRange;
            }

            int tolerance = StrategyEvaluationPreferences.getTolerance();
            				
            if (result >= (100 - tolerance) && !hasSatisfy) {
                if (contribValue > 0)
                    result = Math.max(decompositionValue, 100 - tolerance);
                else
                    result = Math.max(result, 100 - tolerance);
            } else if (result <= (minRange + tolerance) && !hasDeny) {
                if ((contribValue) < 0 && (decompositionValue > 100 * minRange)) // Need to consider that there might be no decomposition
                    result = Math.min(decompositionValue, minRange + tolerance);
                else
                    result = Math.min(result, minRange + tolerance);
            }
        }
        if ((dependencyValue <= 100) && (result > dependencyValue)) {
            result = dependencyValue;
        }
        return result;
    }

    //add confidence value
    protected int evaluateDecomposition(IntentionalElement element, int decompositionValue, Iterator it, ElementLink link) {
        if (element.getDecompositionType().getValue() == DecompositionType.AND) {
            if (!StrategyAlgorithmImplementationHelper.isLegalStereotype(link.getSrc())) {
                if (!it.hasNext() && decompositionValue < minRange){
                    decompositionValue = 0; // case where all sources are tagged "N"     
               // decopConfValue = 0; 
            }
                 //decopDQvalue = 0;
                else {  
                
                	
                    return decompositionValue; // use default value. 
                }
            }

            if (decompositionValue < minRange) {
                
               decompositionValue = ((Evaluation) evaluations.get(link.getSrc())).getEvaluation();
               //decopDQvalue =
            } else
                decompositionValue = evaluateDependency(decompositionValue, link); 
               //decopDQvalue = 

        } else if (element.getDecompositionType().getValue() == DecompositionType.OR || element.getDecompositionType().getValue() == DecompositionType.XOR) {
            if (decompositionValue < minRange) {
                decompositionValue = ((Evaluation) evaluations.get(link.getSrc())).getEvaluation();
                Metadata metaconf = MetadataHelper.getMetaDataObj(link.getSrc(), METADATA_DATAQUALITY); 
                String mc = metaconf.getValue();   
                
               if ((MetadataHelper.getMetaData(element, METADATA_DATAQUALITY)!=null)) {
                MetadataHelper.removeMetaData(element, METADATA_DATAQUALITY); }
                MetadataHelper.addMetaData(element.getGrlspec().getUrnspec(), element, METADATA_DATAQUALITY , metaconf.getValue());
            } else if (decompositionValue < ((Evaluation) evaluations.get(link.getSrc())).getEvaluation()) {
                decompositionValue = ((Evaluation) evaluations.get(link.getSrc())).getEvaluation(); 
                
               // if ()
                Metadata metaconf = MetadataHelper.getMetaDataObj(link.getSrc(), METADATA_DATAQUALITY); 
                String mc = metaconf.getValue();   
                
               if ((MetadataHelper.getMetaData(element, METADATA_DATAQUALITY)!=null)) {
                MetadataHelper.removeMetaData(element, METADATA_DATAQUALITY); }
                MetadataHelper.addMetaData(element.getGrlspec().getUrnspec(), element, METADATA_DATAQUALITY , metaconf.getValue());
               //	 decopConfValue = Integer.parseInt(mc);
           	
            }
        }
        return decompositionValue;
    }

    protected int evaluateDependency(int dependencyValue, ElementLink link) {
        if (dependencyValue > ((Evaluation) evaluations.get(link.getSrc())).getEvaluation()) {
            dependencyValue = ((Evaluation) evaluations.get(link.getSrc())).getEvaluation();
        }
        return dependencyValue;
    }

    protected int evaluateContribution(int[] contributionValues, int contribArrayIt, ElementLink link, Contribution contrib) {
        double resultContrib = computeContributionResult(link, contrib);

        if (resultContrib != 0) {
            contributionValues[contribArrayIt] = (new Double(Math.round(resultContrib))).intValue();
            contribArrayIt++;
        } 
        contCounter = contribArrayIt;
        return contribArrayIt;
    }

    protected double computeContributionResult(ElementLink link, Contribution contrib) {
    	int quantitativeContrib = 0;
        String addAggrValue = "false";
        Metadata metaNumerical = MetadataHelper.getMetaDataObj(link, METADATA_AGGREVAL);
        if(MetadataHelper.getMetaDataObj(link.getSrc(), METADATA_ADDAGGR) != null){
        	addAggrValue = MetadataHelper.getMetaData(link.getSrc(), METADATA_ADDAGGR);
        }
        
        //If "Aggregate Contribution" is enabled and has a value, then 
        //individual contribution of the link is ignored for evaluation
        if((addAggrValue.compareTo("true") == 0) && metaNumerical != null){
        	quantitativeContrib = 0;
        	        	                  	
        }else{
        	quantitativeContrib = EvaluationStrategyManager.getInstance().getActiveQuantitativeContribution(contrib);
        }
    	int srcNode = ((Evaluation) evaluations.get(link.getSrc())).getEvaluation();  
    	Metadata metaconf = MetadataHelper.getMetaDataObj(link.getSrc(), METADATA_DATAQUALITY); 
        String mc = metaconf.getValue();  
        
        double srcNodeDQ; 
        double resultConf ; 
        
        if (metaconf!= null) {
    	// Malak  
        srcNodeDQ = Double.parseDouble(mc); 
        resultConf = (quantitativeContrib * srcNodeDQ) / 100; 
        contConfValue = contConfValue + (new Double(Math.round(resultConf))).intValue();    
        contConfValuePrevious  = (new Double(Math.round(resultConf))).intValue();   
        
         if ((MetadataHelper.getMetaData(link.getDest(), METADATA_DATAQUALITY)!=null)) {
        	  Metadata metaconfDes = MetadataHelper.getMetaDataObj(link.getDest(), METADATA_DATAQUALITY); 
              String mcD = metaconfDes.getValue();    
              int local = Integer.parseInt(mcD);  
              local = local + contConfValuePrevious; 
              MetadataHelper.removeMetaData(link.getDest(), METADATA_DATAQUALITY); 
              MetadataHelper.addMetaData(link.getGrlspec().getUrnspec(), link.getDest(), METADATA_DATAQUALITY , Integer.toString(local));    
          } 
         else
          MetadataHelper.addMetaData(link.getGrlspec().getUrnspec(), link.getDest(), METADATA_DATAQUALITY , Integer.toString(contConfValuePrevious));    
             //	 decopConfValue = Integer.parseInt(mc);
         	
          }
        //confvalue of this node is equal to this value is, if it is not empty, add the value to it 
     //   }  
        else  
        	MetadataHelper.addMetaData(link.getGrlspec().getUrnspec(), link.getDest(), METADATA_DATAQUALITY , Integer.toString(0));
        
        
        double resultContrib;
        resultContrib = (quantitativeContrib * srcNode) / 100;
        return resultContrib;
    }
    
    /**
     * Check if Aggregate Contribution needed for element and compute its value
     */
    protected void getAggregation(IntentionalElement element){
    	
    	Iterator itSrc = element.getLinksSrc().iterator(); // Return the list of elementlink
        while (itSrc.hasNext()) {
            ElementLink linkSrc = (ElementLink) itSrc.next();
            if (linkSrc instanceof Contribution) {
            	
            	boolean isDecomp = false;
            	
            	//Add Metadata to turn on/off aggregation for intentional elements 
                Metadata metaAddAggr = MetadataHelper.getMetaDataObj(element, METADATA_ADDAGGR);
            	
                //Set the metadata to default "false" if not added before
                if (metaAddAggr == null){
            		// Add new run-time metadata for this element
                    URNspec urnSpec = element.getGrlspec().getUrnspec();
            		//DQ
                    MetadataHelper.addMetaData(urnSpec, element, METADATA_ADDAGGR, "disable");
            	}
                for (Object link1: element.getLinksDest()) {
                    if (link1 instanceof Decomposition){
                    	isDecomp = true;
                    	break;
                    }
                }
            	
            	//If the metadata for aggregation is "true" and link isn't mandatory or optional
            	if(!(linkSrc instanceof MandatoryFMLink) && !(linkSrc instanceof OptionalFMLink) && 
            			(MetadataHelper.getMetaData(element, METADATA_ADDAGGR).compareTo("disable") != 0) &&
            					(isDecomp == true) ){
            		
            		if(element.getDecompositionType().getValue() == DecompositionType.AND){
            			computeAggregation(linkSrc,"And");
                	} 
                	else if(element.getDecompositionType().getValue() == DecompositionType.OR){
                		computeAggregation(linkSrc,"Or");
                	}
                	else if(element.getDecompositionType().getValue() == DecompositionType.XOR){
                		computeAggregation(linkSrc,"Xor");
                	}
            	}
            	else if (MetadataHelper.getMetaData(element, METADATA_ADDAGGR).compareTo("disable") == 0){
            		Metadata metaNumerical = MetadataHelper.getMetaDataObj(linkSrc, METADATA_AGGREVAL);
            		if (metaNumerical != null)
                		MetadataHelper.removeMetaData(linkSrc, METADATA_AGGREVAL);
            	}
            }
        }
    }
    
    /**
     * Compute Aggregate Contribution for link provided according to decomposition type
     */
    protected void computeAggregation(ElementLink link, String type){
    	Integer max = 0;
    	int needRangeAnd = 0;
    	String contriValue = "0";
    	int min = 0, count = 0;
    	Iterator it1 = link.getSrc().getLinksDest().iterator(); // Return the list of elementlink
        while (it1.hasNext()) {
        	
            ElementLink link1 = (ElementLink) it1.next();
            if (link1 instanceof Decomposition) {
            	for (Iterator j = link1.getSrc().getLinksSrc().iterator(); j.hasNext();){
            		
            		ElementLink link2 = (ElementLink) j.next();
            		
            		//If the decomposed part of an intentional element is contributing to the same destination
            		if((link2 instanceof Contribution) && (link2.getDest()==link.getDest())){
            			Contribution contrib1 = (Contribution) link2;
            			int minValue = 0, maxValue = 0;
            			Metadata metaAggregate = MetadataHelper.getMetaDataObj(link2, METADATA_AGGREVAL);
            			
            			//If the contribution is aggregate contribution
            			if (metaAggregate != null) {
            				String metaAddAggre = MetadataHelper.getMetaData(link2.getSrc(), METADATA_ADDAGGR);
        					String metaAggreValue = MetadataHelper.getMetaData(link2, METADATA_AGGREVAL);
        					if(metaAggreValue.contains("[")){
        						minValue = Integer.parseInt(metaAggreValue.substring(1, metaAggreValue.indexOf(",")));
        						maxValue = Integer.parseInt(metaAggreValue.substring(metaAggreValue.indexOf(",")+1, metaAggreValue.indexOf("]"))); 
        						needRangeAnd = 1;
        					}
        					else{
        						minValue = Integer.parseInt(metaAggreValue);
        						maxValue = Integer.parseInt(metaAggreValue);
        					}
        					
        					//If "Set Aggregate Contribution" value is "Show", consider both aggregate and individual contribution
        					if (metaAddAggre.compareTo("false") == 0){
        						Contribution contrib = (Contribution) link2;
        						int contri = EvaluationStrategyManager.getInstance().getActiveQuantitativeContribution(contrib);
        						minValue = minValue + contri;
        						maxValue = maxValue + contri;
        					}
        				}
            			if(count == 0){
            				if (metaAggregate != null) {
            					min = minValue;
            					max = maxValue;
            				}
            				else{
            					min = EvaluationStrategyManager.getInstance().getActiveQuantitativeContribution(contrib1);
            					
            					//max will be same as the min in case of normal contribution
            					max = min;
            				}
            				count = 1;
            			}
            			else{
            				if (metaAggregate == null) {
            					minValue = EvaluationStrategyManager.getInstance().getActiveQuantitativeContribution(contrib1);
            					
            					//In case of normal contribution, no max or min values
            					maxValue = minValue;
            				}	
            				
            				//Calculate minimum
            				if(type.compareTo("Or") == 0){
            					if (min >= 0 && min >= minValue)
            						min = minValue;
            					else if (min < 0 && minValue <0)
            						min += minValue;
            				}
            				else if(type.compareTo("Xor") == 0){
	            				if(min >= minValue)
	            					min = minValue;
	            			}
            				else{
            					min += minValue;
            				}
            				
            				//Calculate maximum
            				if(type.compareTo("Xor") == 0){
            					if(max <= maxValue)
    	        					max = maxValue;
    	        			}
            				else if(type.compareTo("Or") == 0){
            					if (max >= 0 && maxValue >= 0)
            						max += maxValue;
            					else if (max < 0 && maxValue >= max)
            						max = maxValue;
            				}
            				else{
            					max += maxValue;
            				}
            				          				
            			}
            		}
            	}
            	
            }
        }
        
        //Cap the contribution values to "-100" as minimum and "100" as maximum
        if (min <= -100){
			min = -100;
		}
        if (max <= -100){
			max = -100;
		}
        if (min >= 100){
			min = 100;
		}
		if (max >= 100){
			max = 100;
		}
		if(type.compareTo("Xor") == 0 || type.compareTo("Or") == 0 || (type.compareTo("And") == 0 && needRangeAnd == 1)){
			contriValue = "[" + min + "," + max + "]";
		}
		else{
			contriValue = max.toString();
		}
        Metadata metaNumerical = MetadataHelper.getMetaDataObj(link, METADATA_AGGREVAL);
        if (metaNumerical != null) {
                // Run-time metadata already exists for this element
                metaNumerical.setValue(contriValue);
            } else {
                // Add new run-time metadata for this element
                URNspec urnSpec = link.getGrlspec().getUrnspec();
                MetadataHelper.addMetaData(urnSpec, link, METADATA_AGGREVAL, contriValue);
            }
    }

    /*
     * (non-Javadoc)
     * 
     * @see seg.jUCMNav.extensionpoints.IGRLStrategyAlgorithm#getActorEvaluation(grl.Actor)
     */
    public int getActorEvaluation(Actor actor) {
      return StrategyAlgorithmImplementationHelper.defaultActorEvaluation(actor);
    }

    @Override
    public boolean isConstraintSolverAlgorithm() {
        return false;
    }

}
