discover method

List<Pattern> discover(
  1. Map<String, String> conceptLabels
)

Discovers all patterns that exceed minOccurrences and minConfidence.

Returns newly discovered Pattern objects.

Implementation

List<Pattern> discover(Map<String, String> conceptLabels) {
  final newPatterns = <Pattern>[];

  // 1. Co-occurrence patterns
  for (final entry in _coOccurrence.entries) {
    if (entry.value < minOccurrences) continue;

    final ids = _splitCoKey(entry.key);
    if (ids.length != 2) continue;

    final freq1 = _conceptFreq[ids[0]] ?? 1;
    final freq2 = _conceptFreq[ids[1]] ?? 1;
    final support = entry.value / math.max(freq1, freq2);

    if (support >= minConfidence) {
      final label1 = conceptLabels[ids[0]] ?? ids[0].substring(0, 8);
      final label2 = conceptLabels[ids[1]] ?? ids[1].substring(0, 8);
      final p = Pattern(
        id: _uuid.v4(),
        description: 'Co-occurrence: "$label1" with "$label2"',
        involvedConceptIds: ids,
        confidence: support,
        occurrenceCount: entry.value,
      );
      if (!_isDuplicate(p)) {
        newPatterns.add(p);
        _discoveredPatterns.add(p);
      }
    }
  }

  // 2. Sequence patterns
  for (final entry in _sequences.entries) {
    if (entry.value < minOccurrences) continue;

    final parts = entry.key.split('→');
    if (parts.length != 2) continue;

    final antecedent = parts[0];
    final consequent = parts[1];
    final antFreq = _conceptFreq[antecedent] ?? 1;
    final confidence = entry.value / antFreq;

    if (confidence >= minConfidence) {
      final lA = conceptLabels[antecedent] ?? antecedent.substring(0, 8);
      final lB = conceptLabels[consequent] ?? consequent.substring(0, 8);
      final p = Pattern(
        id: _uuid.v4(),
        description: 'Sequence: "$lA" is followed by "$lB"',
        involvedConceptIds: [antecedent, consequent],
        confidence: confidence,
        occurrenceCount: entry.value,
      );
      if (!_isDuplicate(p)) {
        newPatterns.add(p);
        _discoveredPatterns.add(p);
      }
    }
  }

  if (newPatterns.isNotEmpty) {
    _logger.info(
        'Discovered ${newPatterns.length} new pattern(s) '
        '(total: ${_discoveredPatterns.length})');
  }

  return newPatterns;
}