use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum LexicalCoherenceError {
#[error("Empty text provided for lexical analysis")]
EmptyText,
#[error("Invalid lexical chain configuration: {0}")]
InvalidConfiguration(String),
#[error("Semantic lexicon error: {0}")]
SemanticLexiconError(String),
#[error("Word processing error: {0}")]
WordProcessingError(String),
#[error("Chain building failed: {0}")]
ChainBuildingError(String),
#[error("Coherence calculation failed: {0}")]
CalculationError(String),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Hash, Eq)]
pub enum SemanticRelationship {
Synonymy,
Hyponymy,
Meronymy,
Antonymy,
Association,
Sequential,
Causal,
Temporal,
Morphological,
Collocation,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum LexicalChainType {
Repetition,
Synonymous,
Hierarchical,
Meronymic,
Thematic,
Morphological,
Collocational,
Mixed,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum CohesionDeviceType {
Repetition,
Synonymy,
Hyponymy,
Meronymy,
Collocation,
Antonymy,
Morphological,
Bridging,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LexicalCoherenceConfig {
pub general: GeneralLexicalConfig,
pub chains: ChainBuildingConfig,
pub semantic: SemanticAnalysisConfig,
pub cohesion: CohesionAnalysisConfig,
pub advanced: AdvancedLexicalConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GeneralLexicalConfig {
pub enable_caching: bool,
pub parallel_processing: bool,
pub detailed_metrics: bool,
pub min_word_length: usize,
pub max_analysis_depth: usize,
pub debug_output: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChainBuildingConfig {
pub enabled: bool,
pub min_chain_length: usize,
pub max_chain_length: usize,
pub max_distance: usize,
pub similarity_threshold: f64,
pub use_semantic_relations: bool,
pub use_morphological_relations: bool,
pub position_aware: bool,
pub chain_type_weights: HashMap<LexicalChainType, f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SemanticAnalysisConfig {
pub enabled: bool,
pub use_builtin_lexicon: bool,
pub similarity_threshold: f64,
pub max_field_size: usize,
pub morphological_analysis: bool,
pub character_similarity_weight: f64,
pub semantic_similarity_weight: f64,
pub morphological_similarity_weight: f64,
pub relationship_weights: HashMap<SemanticRelationship, f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CohesionAnalysisConfig {
pub enabled: bool,
pub analyze_repetition: bool,
pub analyze_synonymy: bool,
pub analyze_hyponymy: bool,
pub analyze_meronymy: bool,
pub analyze_collocation: bool,
pub analyze_antonymy: bool,
pub analyze_morphological: bool,
pub analyze_bridging: bool,
pub device_weights: HashMap<CohesionDeviceType, f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdvancedLexicalConfig {
pub enabled: bool,
pub network_analysis: bool,
pub information_measures: bool,
pub cognitive_load_estimation: bool,
pub discourse_alignment: bool,
pub temporal_analysis: bool,
pub lexical_diversity: bool,
pub pattern_statistics: bool,
}
impl Default for LexicalCoherenceConfig {
fn default() -> Self {
Self {
general: GeneralLexicalConfig::default(),
chains: ChainBuildingConfig::default(),
semantic: SemanticAnalysisConfig::default(),
cohesion: CohesionAnalysisConfig::default(),
advanced: AdvancedLexicalConfig::default(),
}
}
}
impl Default for GeneralLexicalConfig {
fn default() -> Self {
Self {
enable_caching: true,
parallel_processing: true,
detailed_metrics: false,
min_word_length: 3,
max_analysis_depth: 10,
debug_output: false,
}
}
}
impl Default for ChainBuildingConfig {
fn default() -> Self {
Self {
enabled: true,
min_chain_length: 2,
max_chain_length: 50,
max_distance: 10,
similarity_threshold: 0.5,
use_semantic_relations: true,
use_morphological_relations: true,
position_aware: true,
chain_type_weights: Self::default_chain_type_weights(),
}
}
}
impl ChainBuildingConfig {
fn default_chain_type_weights() -> HashMap<LexicalChainType, f64> {
let mut weights = HashMap::new();
weights.insert(LexicalChainType::Repetition, 1.0);
weights.insert(LexicalChainType::Synonymous, 0.9);
weights.insert(LexicalChainType::Hierarchical, 0.8);
weights.insert(LexicalChainType::Meronymic, 0.7);
weights.insert(LexicalChainType::Thematic, 0.8);
weights.insert(LexicalChainType::Morphological, 0.6);
weights.insert(LexicalChainType::Collocational, 0.7);
weights.insert(LexicalChainType::Mixed, 0.5);
weights
}
}
impl Default for SemanticAnalysisConfig {
fn default() -> Self {
Self {
enabled: true,
use_builtin_lexicon: true,
similarity_threshold: 0.6,
max_field_size: 20,
morphological_analysis: true,
character_similarity_weight: 0.3,
semantic_similarity_weight: 0.5,
morphological_similarity_weight: 0.2,
relationship_weights: Self::default_relationship_weights(),
}
}
}
impl SemanticAnalysisConfig {
fn default_relationship_weights() -> HashMap<SemanticRelationship, f64> {
let mut weights = HashMap::new();
weights.insert(SemanticRelationship::Synonymy, 1.0);
weights.insert(SemanticRelationship::Hyponymy, 0.8);
weights.insert(SemanticRelationship::Meronymy, 0.7);
weights.insert(SemanticRelationship::Antonymy, 0.6);
weights.insert(SemanticRelationship::Association, 0.5);
weights.insert(SemanticRelationship::Sequential, 0.4);
weights.insert(SemanticRelationship::Causal, 0.6);
weights.insert(SemanticRelationship::Temporal, 0.5);
weights.insert(SemanticRelationship::Morphological, 0.7);
weights.insert(SemanticRelationship::Collocation, 0.6);
weights
}
}
impl Default for CohesionAnalysisConfig {
fn default() -> Self {
Self {
enabled: true,
analyze_repetition: true,
analyze_synonymy: true,
analyze_hyponymy: true,
analyze_meronymy: true,
analyze_collocation: true,
analyze_antonymy: false,
analyze_morphological: true,
analyze_bridging: false,
device_weights: Self::default_device_weights(),
}
}
}
impl CohesionAnalysisConfig {
fn default_device_weights() -> HashMap<CohesionDeviceType, f64> {
let mut weights = HashMap::new();
weights.insert(CohesionDeviceType::Repetition, 1.0);
weights.insert(CohesionDeviceType::Synonymy, 0.9);
weights.insert(CohesionDeviceType::Hyponymy, 0.8);
weights.insert(CohesionDeviceType::Meronymy, 0.7);
weights.insert(CohesionDeviceType::Collocation, 0.6);
weights.insert(CohesionDeviceType::Antonymy, 0.5);
weights.insert(CohesionDeviceType::Morphological, 0.7);
weights.insert(CohesionDeviceType::Bridging, 0.4);
weights
}
}
impl Default for AdvancedLexicalConfig {
fn default() -> Self {
Self {
enabled: false,
network_analysis: false,
information_measures: false,
cognitive_load_estimation: false,
discourse_alignment: false,
temporal_analysis: false,
lexical_diversity: false,
pattern_statistics: false,
}
}
}
impl LexicalCoherenceConfig {
pub fn minimal() -> Self {
Self {
general: GeneralLexicalConfig {
enable_caching: false,
parallel_processing: false,
detailed_metrics: false,
min_word_length: 3,
max_analysis_depth: 3,
debug_output: false,
},
chains: ChainBuildingConfig {
enabled: true,
min_chain_length: 2,
max_chain_length: 10,
max_distance: 5,
similarity_threshold: 0.7,
use_semantic_relations: false,
use_morphological_relations: false,
position_aware: false,
chain_type_weights: ChainBuildingConfig::default_chain_type_weights(),
},
semantic: SemanticAnalysisConfig {
enabled: false,
use_builtin_lexicon: false,
similarity_threshold: 0.8,
max_field_size: 5,
morphological_analysis: false,
character_similarity_weight: 1.0,
semantic_similarity_weight: 0.0,
morphological_similarity_weight: 0.0,
relationship_weights: SemanticAnalysisConfig::default_relationship_weights(),
},
cohesion: CohesionAnalysisConfig {
enabled: true,
analyze_repetition: true,
analyze_synonymy: false,
analyze_hyponymy: false,
analyze_meronymy: false,
analyze_collocation: false,
analyze_antonymy: false,
analyze_morphological: false,
analyze_bridging: false,
device_weights: CohesionAnalysisConfig::default_device_weights(),
},
advanced: AdvancedLexicalConfig {
enabled: false,
network_analysis: false,
information_measures: false,
cognitive_load_estimation: false,
discourse_alignment: false,
temporal_analysis: false,
lexical_diversity: false,
pattern_statistics: false,
},
}
}
pub fn comprehensive() -> Self {
Self {
general: GeneralLexicalConfig {
enable_caching: true,
parallel_processing: true,
detailed_metrics: true,
min_word_length: 2,
max_analysis_depth: 15,
debug_output: false,
},
chains: ChainBuildingConfig {
enabled: true,
min_chain_length: 2,
max_chain_length: 100,
max_distance: 20,
similarity_threshold: 0.3,
use_semantic_relations: true,
use_morphological_relations: true,
position_aware: true,
chain_type_weights: ChainBuildingConfig::default_chain_type_weights(),
},
semantic: SemanticAnalysisConfig {
enabled: true,
use_builtin_lexicon: true,
similarity_threshold: 0.4,
max_field_size: 50,
morphological_analysis: true,
character_similarity_weight: 0.3,
semantic_similarity_weight: 0.5,
morphological_similarity_weight: 0.2,
relationship_weights: SemanticAnalysisConfig::default_relationship_weights(),
},
cohesion: CohesionAnalysisConfig {
enabled: true,
analyze_repetition: true,
analyze_synonymy: true,
analyze_hyponymy: true,
analyze_meronymy: true,
analyze_collocation: true,
analyze_antonymy: true,
analyze_morphological: true,
analyze_bridging: true,
device_weights: CohesionAnalysisConfig::default_device_weights(),
},
advanced: AdvancedLexicalConfig {
enabled: true,
network_analysis: true,
information_measures: true,
cognitive_load_estimation: true,
discourse_alignment: true,
temporal_analysis: true,
lexical_diversity: true,
pattern_statistics: true,
},
}
}
pub fn for_academic_papers() -> Self {
let mut config = Self::comprehensive();
config.chains.min_chain_length = 3;
config.chains.similarity_threshold = 0.4;
config.semantic.similarity_threshold = 0.5;
config.semantic.max_field_size = 30;
config.advanced.enabled = true;
config.advanced.discourse_alignment = true;
config
}
pub fn for_creative_writing() -> Self {
let mut config = Self::default();
config.chains.similarity_threshold = 0.4;
config.chains.max_distance = 15;
config.semantic.enabled = true;
config.semantic.morphological_analysis = true;
config.advanced.temporal_analysis = true;
config.advanced.lexical_diversity = true;
config
}
pub fn for_technical_docs() -> Self {
let mut config = Self::default();
config.chains.similarity_threshold = 0.6;
config.cohesion.analyze_repetition = true;
config.cohesion.analyze_morphological = true;
config.semantic.similarity_threshold = 0.7;
config
}
pub fn builder() -> LexicalCoherenceConfigBuilder {
LexicalCoherenceConfigBuilder::new()
}
}
pub struct LexicalCoherenceConfigBuilder {
config: LexicalCoherenceConfig,
}
impl LexicalCoherenceConfigBuilder {
pub fn new() -> Self {
Self {
config: LexicalCoherenceConfig::default(),
}
}
pub fn general_config(mut self, general: GeneralLexicalConfig) -> Self {
self.config.general = general;
self
}
pub fn chain_config(mut self, chains: ChainBuildingConfig) -> Self {
self.config.chains = chains;
self
}
pub fn semantic_config(mut self, semantic: SemanticAnalysisConfig) -> Self {
self.config.semantic = semantic;
self
}
pub fn cohesion_config(mut self, cohesion: CohesionAnalysisConfig) -> Self {
self.config.cohesion = cohesion;
self
}
pub fn advanced_config(mut self, advanced: AdvancedLexicalConfig) -> Self {
self.config.advanced = advanced;
self
}
pub fn build(self) -> LexicalCoherenceConfig {
self.config
}
}