<commit_before>part of fuzzylogic;

/**
 * FuzzyValue is a FuzzyVariable that was initialized with a value (normally
 * by calling [FuzzyVariable.assign()] just before resolving the [RuleBase]).
 */
class FuzzyValue<T> {
  FuzzyValue(this.variable, [T crispValue]) {
    assert(variable != null);
    degreesOfTruth = new Map<FuzzySet<T>, num>();
    variable.sets.forEach((set) => degreesOfTruth[set] = 0.0);
    
    if (crispValue != null) {
      this.crispValue = crispValue;
    }
  }
  
  FuzzyVariable<T> variable;
  Map<FuzzySet<T>, num> degreesOfTruth; // TODO get - throw if unitialized
  T _crispValue; // TODO get, set
  num _crispValueConfidence;
  
  T get crispValue {
    if (_crispValue != null) {
      return _crispValue;
    } else {
      _computeCrispValue();
      return _crispValue;
    }
  }
  
  num get confidence {
    // TODO
    return _crispValueConfidence;
  }
  
  set crispValue(T value) {
    _crispValue = value;
    _crispValueConfidence = 1.0;
    _setDegreesOfTruthFromCrispValue();
  }
  
  /**
   * Sets degrees of truth of a variable which has been assigned a crisp value.
   */
  void _setDegreesOfTruthFromCrispValue() {
    variable.sets.forEach((set) => 
        set.setDegreeOfTruth(set.getDegreeOfMembership(_crispValue), [this]));
  }
  
  /**
   * Compute the crisp value using the Average of Maxima method.
   */
  void _computeCrispValue() {
    assert(T == num || T == int);  // Average of Maxima only works on numeric crisp values.
    num numerator = variable.sets.fold(0, (sum, fuzzySet) => 
        sum + (fuzzySet.representativeValue as num) * degreesOfTruth[fuzzySet]);
    num denominator = degreesOfTruth.values.fold(0, (sum, dot) => sum + dot);
    if (denominator == 0) {
      // No confidence.
      _crispValue = null;
    } else if (T == int) {
      _crispValue = numerator ~/ denominator;
    } else if (T == num) {
      _crispValue = numerator / denominator;
    } else {
      throw new StateError("Cannot compute AvMax for non-numeric values.");
    }
    _crispValueConfidence = degreesOfTruth.values.reduce(max);
  }
  
  /**
   * Sets the degree of truth for a [FuzzySet] which is a part of this 
   * [FuzzyValue].
   */
  void setDegreeOfTruth(FuzzySet<T> set, num degreeOfTruth) {
    assert(variable.sets.contains(set));
    var currentDegreeOfTruth = degreesOfTruth[set];
    if (currentDegreeOfTruth == null) { 
      degreesOfTruth[set] = degreeOfTruth;
    } else if (currentDegreeOfTruth < degreeOfTruth) {
      degreesOfTruth[set] = degreeOfTruth;
    }
  }
}
<commit_msg>Hotfix dart2js bug with <T><commit_after>part of fuzzylogic;

/**
 * FuzzyValue is a FuzzyVariable that was initialized with a value (normally
 * by calling [FuzzyVariable.assign()] just before resolving the [RuleBase]).
 */
class FuzzyValue<T> {
  FuzzyValue(this.variable, [T crispValue]) {
    assert(variable != null);
    degreesOfTruth = new Map<FuzzySet<T>, num>();
    variable.sets.forEach((set) => degreesOfTruth[set] = 0.0);
    
    if (crispValue != null) {
      this.crispValue = crispValue;
    }
  }
  
  FuzzyVariable<T> variable;
  Map<FuzzySet<T>, num> degreesOfTruth; // TODO get - throw if unitialized
  T _crispValue; // TODO get, set
  num _crispValueConfidence;
  
  T get crispValue {
    if (_crispValue != null) {
      return _crispValue;
    } else {
      _computeCrispValue();
      return _crispValue;
    }
  }
  
  num get confidence {
    // TODO
    return _crispValueConfidence;
  }
  
  set crispValue(T value) {
    _crispValue = value;
    _crispValueConfidence = 1.0;
    _setDegreesOfTruthFromCrispValue();
  }
  
  /**
   * Sets degrees of truth of a variable which has been assigned a crisp value.
   */
  void _setDegreesOfTruthFromCrispValue() {
    variable.sets.forEach((set) => 
        set.setDegreeOfTruth(set.getDegreeOfMembership(_crispValue), [this]));
  }
  
  /**
   * Compute the crisp value using the Average of Maxima method.
   */
  void _computeCrispValue() {
    assert(T == num || T == int);  // Average of Maxima only works on numeric crisp values.
    num numerator = variable.sets.fold(0, (sum, fuzzySet) => 
        sum + (fuzzySet.representativeValue as num) * degreesOfTruth[fuzzySet]);
    num denominator = degreesOfTruth.values.fold(0, (sum, dot) => sum + dot);
    if (denominator == 0) {
      // No confidence.
      _crispValue = null;
    } else if (T == int) {
      _crispValue = numerator ~/ denominator;
    } else if (T == num) {
      _crispValue = numerator / denominator;
    } else {
      _crispValue = numerator / denominator;
      // TODO: the (T == num) doesn't work in dart2js 
      // uncomment below and delete above
      //throw new StateError("Cannot compute AvMax for non-numeric values.");
    }
    _crispValueConfidence = degreesOfTruth.values.reduce(max);
  }
  
  /**
   * Sets the degree of truth for a [FuzzySet] which is a part of this 
   * [FuzzyValue].
   */
  void setDegreeOfTruth(FuzzySet<T> set, num degreeOfTruth) {
    assert(variable.sets.contains(set));
    var currentDegreeOfTruth = degreesOfTruth[set];
    if (currentDegreeOfTruth == null) { 
      degreesOfTruth[set] = degreeOfTruth;
    } else if (currentDegreeOfTruth < degreeOfTruth) {
      degreesOfTruth[set] = degreeOfTruth;
    }
  }
}

{'fraction_non_alphanumeric': 0.11534090909090909, 'fraction_numerical': 0.0030303030303030303, 'mean_word_length': 2.9587706146926536, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1633045', 'n_tokens_mistral': 1883, 'n_tokens_neox': 1799, 'n_words': 444}