synthesiseThought method
Synthesises a coherent natural-language thought from active concepts.
Called when no inference rule fires — falls back to a descriptive combination of the most salient concepts.
Implementation
String synthesiseThought(List<Concept> active) {
if (active.isEmpty) return '(Nothing is currently in focus.)';
final sorted = List.of(active)
..sort((a, b) =>
b.calculateSalience().compareTo(a.calculateSalience()));
final primary = sorted.first;
final secondary = sorted.length > 1 ? sorted[1] : null;
final tertiary = sorted.length > 2 ? sorted[2] : null;
// Check if the primary concept implies wanting something
final wantsPattern = RegExp(
r'\b(hungry|thirsty|tired|cold|hot|want|need|desire)\b',
caseSensitive: false);
final hasWant = wantsPattern.hasMatch(primary.content) ||
(secondary != null && wantsPattern.hasMatch(secondary.content));
// Check for spatial relationship
final spatialPattern = RegExp(
r'\b(on|above|below|near|beside|next to|over|under)\b',
caseSensitive: false);
final hasSpatial = spatialPattern.hasMatch(primary.content);
// Check causal cues
final causalChain = _causal.buildCausalChain(primary.id);
if (causalChain.length > 1) {
final labels = {
for (final n in _graph.getAllNodes())
n.id: n.concept.content,
};
final chainDesc =
_causal.describeCausality(causalChain, labels);
if (chainDesc.isNotEmpty) return chainDesc;
}
if (hasWant && secondary != null) {
return '${_capitalise(primary.content)} wants '
'${secondary.content}.';
}
if (hasSpatial && secondary != null) {
return '${_capitalise(primary.content)} and '
'${secondary.content} are spatially related.';
}
if (secondary != null && tertiary != null) {
return '${_capitalise(primary.content)} involves '
'${secondary.content} and ${tertiary.content}.';
}
if (secondary != null) {
return '${_capitalise(primary.content)} is connected '
'to ${secondary.content}.';
}
return _capitalise(primary.content) + '.';
}