use serde::{Deserialize, Serialize};
use super::{
execute_profile_based_thinktool, CompositeInstruction, ConstraintResult, InterleavedProtocol,
M2ThinkTool, M2ThinkToolResult, ProfileType,
};
use crate::error::Result;
use std::time::Instant;
pub struct EnhancedLaserLogic {
pub module_id: String,
pub version: String,
pub composite_constraints: Vec<CompositeInstruction>,
pub interleaved_protocol: InterleavedProtocol,
pub fallacy_database: FallacyDatabase,
}
impl Default for EnhancedLaserLogic {
fn default() -> Self {
Self::new()
}
}
impl EnhancedLaserLogic {
pub fn new() -> Self {
let module_id = "enhanced_laserlogic".to_string();
let version = "2.0.0-minimax".to_string();
Self {
module_id: module_id.clone(),
version,
composite_constraints: Self::create_composite_constraints(),
interleaved_protocol: Self::create_interleaved_protocol(module_id),
fallacy_database: FallacyDatabase::new(),
}
}
fn create_composite_constraints() -> Vec<CompositeInstruction> {
vec![
CompositeInstruction::SystemPrompt(super::composite_constraints::SystemPrompt {
template: r#"You are LaserLogic, a precision deductive reasoning engine powered by MiniMax M2.
Your task is to perform rigorous logical analysis with comprehensive fallacy detection.
CONSTRAINTS:
- Extract all logical components (premises, conclusion, assumptions)
- Validate logical structure and soundness
- Detect all possible fallacies with high precision
- Provide confidence scores for each finding
- Maintain strict logical consistency
- Complete analysis within 4 seconds
- Output structured logical analysis in JSON
LOGICAL ANALYSIS FRAMEWORK:
1. Premise Extraction: Identify all stated and implicit premises
2. Conclusion Identification: Determine the main conclusion
3. Logical Structure Analysis: Map the logical flow
4. Validity Assessment: Check if premises logically support conclusion
5. Fallacy Detection: Identify any logical fallacies
6. Soundness Evaluation: Assess truth of premises
7. Strength Rating: Overall logical strength (0.0-1.0)
FALLACY CATEGORIES TO DETECT:
- Ad Hominem, Straw Man, False Dichotomy
- Appeal to Authority, Circular Reasoning
- Hasty Generalization, Post Hoc Ergo Propter Hoc
- Slippery Slope, Red Herring, Appeal to Emotion
- False Cause, Loaded Question, Bandwagon
- Composition/Division, Accident, Converse Accident
Argument to analyze: {{argument}}"#.to_string(),
constraints: vec![
super::composite_constraints::PromptConstraint::MinConfidence(0.8),
super::composite_constraints::PromptConstraint::RequiredKeywords(vec!["premise".to_string(), "conclusion".to_string(), "logical".to_string()]),
super::composite_constraints::PromptConstraint::ForbiddenKeywords(vec!["probably".to_string(), "might be".to_string(), "possibly".to_string()]),
],
variables: {
let mut vars = std::collections::HashMap::new();
vars.insert("argument".to_string(), "{{argument}}".to_string());
vars
},
token_limit: Some(1500),
}),
CompositeInstruction::UserQuery(super::composite_constraints::UserQuery {
raw_text: "{{argument}}".to_string(),
sanitized_text: "{{argument}}".to_string(),
intent: super::composite_constraints::QueryIntent::Analytical,
complexity_score: 0.7,
required_tools: vec!["laserlogic".to_string(), "fallacy_detection".to_string()],
}),
CompositeInstruction::MemoryContext(super::composite_constraints::MemoryContext {
context_id: "laserlogic_session".to_string(),
content: "Precision logical reasoning session context".to_string(),
relevance_score: 0.9,
retention_policy: super::composite_constraints::RetentionPolicy::Session,
dependencies: vec![],
}),
CompositeInstruction::ToolSchema(super::composite_constraints::ToolSchema {
tool_name: "laserlogic".to_string(),
input_schema: super::composite_constraints::SchemaDefinition {
format: super::composite_constraints::SchemaFormat::JSON,
fields: vec![
super::composite_constraints::SchemaField {
name: "argument".to_string(),
field_type: super::composite_constraints::FieldType::String,
required: true,
constraints: vec![
super::composite_constraints::FieldConstraint::MinLength(20),
super::composite_constraints::FieldConstraint::MaxLength(2000),
],
}
],
validation_rules: vec![],
},
output_schema: super::composite_constraints::SchemaDefinition {
format: super::composite_constraints::SchemaFormat::JSON,
fields: vec![
super::composite_constraints::SchemaField {
name: "conclusion".to_string(),
field_type: super::composite_constraints::FieldType::String,
required: true,
constraints: vec![],
},
super::composite_constraints::SchemaField {
name: "premises".to_string(),
field_type: super::composite_constraints::FieldType::Array(Box::new(super::composite_constraints::FieldType::String)),
required: true,
constraints: vec![],
},
super::composite_constraints::SchemaField {
name: "fallacies".to_string(),
field_type: super::composite_constraints::FieldType::Array(Box::new(super::composite_constraints::FieldType::Object)),
required: true,
constraints: vec![],
}
],
validation_rules: vec![],
},
constraints: vec![],
}),
]
}
fn create_interleaved_protocol(module_id: String) -> InterleavedProtocol {
use super::interleaved_thinking::{
CheckType, OptimizationParameters, PatternStep, PatternStepType, PatternType,
ProtocolOptimization, ThinkingPattern, ValidationCriterion,
};
InterleavedProtocol {
protocol_id: format!("{}_protocol", module_id),
name: "Enhanced LaserLogic Protocol".to_string(),
version: "2.0.0-minimax".to_string(),
description:
"M2-enhanced precision deductive reasoning with comprehensive fallacy detection"
.to_string(),
patterns: vec![ThinkingPattern {
pattern_id: "laserlogic_precision_pattern".to_string(),
name: "LaserLogic Precision Analysis".to_string(),
description: "Rigorous logical analysis with multi-stage validation".to_string(),
pattern_type: PatternType::Linear,
steps: vec![
PatternStep {
step_id: "premise_extraction".to_string(),
step_type: PatternStepType::InputProcessing,
description:
"Extract all premises, conclusions, and assumptions from argument"
.to_string(),
prerequisites: vec![],
outputs: vec![],
validation_criteria: vec![ValidationCriterion {
criterion_id: "premise_completeness".to_string(),
check_type: CheckType::Completeness,
threshold: 0.9,
description: "Must extract all premises and conclusions".to_string(),
}],
},
PatternStep {
step_id: "logical_structure_analysis".to_string(),
step_type: PatternStepType::Reasoning,
description: "Analyze logical structure and flow of argument".to_string(),
prerequisites: vec!["premise_extraction".to_string()],
outputs: vec![],
validation_criteria: vec![ValidationCriterion {
criterion_id: "structure_clarity".to_string(),
check_type: CheckType::LogicalConsistency,
threshold: 0.9,
description: "Logical structure must be clearly mapped".to_string(),
}],
},
PatternStep {
step_id: "fallacy_detection".to_string(),
step_type: PatternStepType::Analysis,
description: "Detect logical fallacies using comprehensive database"
.to_string(),
prerequisites: vec!["logical_structure_analysis".to_string()],
outputs: vec![],
validation_criteria: vec![ValidationCriterion {
criterion_id: "fallacy_coverage".to_string(),
check_type: CheckType::Completeness,
threshold: 0.8,
description: "Must check all major fallacy categories".to_string(),
}],
},
PatternStep {
step_id: "validity_assessment".to_string(),
step_type: PatternStepType::Evaluation,
description: "Assess logical validity and soundness of argument"
.to_string(),
prerequisites: vec!["fallacy_detection".to_string()],
outputs: vec![],
validation_criteria: vec![ValidationCriterion {
criterion_id: "validity_precision".to_string(),
check_type: CheckType::ConfidenceThreshold,
threshold: 0.85,
description: "Validity assessment must be highly precise".to_string(),
}],
},
],
validation_rules: vec![],
optimization_params: OptimizationParameters {
max_iterations: Some(2),
confidence_threshold: 0.85,
time_limit_ms: Some(4000),
token_limit: Some(1800),
parallelization_level: 1,
},
}],
default_pattern: "laserlogic_precision_pattern".to_string(),
optimization_config: ProtocolOptimization {
auto_validation: true,
cross_validation_enabled: true,
parallel_processing: false,
adaptive_patterns: false,
performance_target: 0.92,
cost_optimization: true,
},
}
}
async fn execute_m2_methodology(
&self,
argument: &str,
profile: ProfileType,
) -> Result<M2ThinkToolResult> {
let start_time = Instant::now();
use super::composite_constraints::ValidationInputs;
let system_prompt = self
.composite_constraints
.iter()
.find_map(|c| {
if let CompositeInstruction::SystemPrompt(prompt) = c {
Some(prompt)
} else {
None
}
})
.unwrap();
let user_query = self
.composite_constraints
.iter()
.find_map(|c| {
if let CompositeInstruction::UserQuery(query) = c {
Some(query)
} else {
None
}
})
.unwrap();
let memory_context = self
.composite_constraints
.iter()
.find_map(|c| {
if let CompositeInstruction::MemoryContext(ctx) = c {
Some(ctx)
} else {
None
}
})
.unwrap();
let tool_schema = self
.composite_constraints
.iter()
.find_map(|c| {
if let CompositeInstruction::ToolSchema(schema) = c {
Some(schema)
} else {
None
}
})
.unwrap();
let validation_inputs = ValidationInputs::new()
.with_system_prompt(system_prompt)
.with_user_query(user_query)
.with_memory_context(memory_context)
.add_tool_schema("laserlogic", tool_schema);
let constraint_engine = super::composite_constraints::ConstraintEngine::new();
let constraint_result = constraint_engine.validate_all(&validation_inputs);
let mut base_output = serde_json::json!({
"conclusion": null,
"premises": [],
"validity": "Pending",
"soundness": "Pending",
"fallacies": [],
"logical_structure": {},
"strength_rating": 0.0,
"metadata": {
"execution_profile": format!("{:?}", profile),
"m2_enhanced": true,
"protocol_version": self.version,
"fallacy_database_version": self.fallacy_database.version
}
});
use super::interleaved_thinking::MultiStepReasoning;
let pattern = &self.interleaved_protocol.patterns[0];
let mut reasoning_engine = MultiStepReasoning::new(pattern.clone());
let interleaved_result = reasoning_engine.execute(argument).await?;
let detected_fallacies = self.fallacy_database.detect_fallacies(argument).await?;
if let Some(serde_json::Value::Array(premises)) = base_output.get_mut("premises") {
for step in &interleaved_result.steps_completed {
if step.step_id == "premise_extraction" {
for node in &step.reasoning_chain {
if node.reasoning_type
== super::interleaved_thinking::ReasoningType::Deductive
{
premises.push(serde_json::json!({
"premise": node.content,
"confidence": node.confidence,
"type": "explicit"
}));
}
}
}
}
}
if let Some(serde_json::Value::Array(fallacies)) = base_output.get_mut("fallacies") {
for fallacy in detected_fallacies {
fallacies.push(serde_json::json!({
"type": fallacy.fallacy_type,
"description": fallacy.description,
"confidence": fallacy.confidence,
"location": fallacy.location,
"severity": fallacy.severity
}));
}
}
let processing_time = start_time.elapsed().as_millis() as u64;
let token_count = (processing_time / 8) as u32;
let mut result = M2ThinkToolResult::new(self.module_id.clone(), base_output);
result.constraint_adherence = constraint_result;
result.interleaved_steps = interleaved_result.steps_completed;
result.processing_time_ms = processing_time;
result.token_count = token_count;
result.confidence = self.calculate_profile_confidence(&result, profile);
Ok(result)
}
fn calculate_profile_confidence(
&self,
result: &M2ThinkToolResult,
profile: ProfileType,
) -> f64 {
let base_confidence = match profile {
ProfileType::Quick => 0.80,
ProfileType::Balanced => 0.90,
ProfileType::Deep => 0.95,
ProfileType::Paranoid => 0.98,
};
let constraint_bonus = match &result.constraint_adherence {
ConstraintResult::Passed(score) => score * 0.05,
ConstraintResult::Failed(_) => -0.3,
ConstraintResult::Pending => 0.0,
};
let fallacy_bonus = if !result.interleaved_steps.is_empty() {
let fallacy_steps: Vec<_> = result
.interleaved_steps
.iter()
.filter(|step| step.step_id == "fallacy_detection")
.collect();
if !fallacy_steps.is_empty() && fallacy_steps[0].cross_validation_passed {
0.1
} else {
0.0
}
} else {
0.0
};
(base_confidence + constraint_bonus + fallacy_bonus).clamp(0.0, 1.0)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FallacyDatabase {
pub version: String,
pub fallacies: Vec<FallacyDefinition>,
}
impl Default for FallacyDatabase {
fn default() -> Self {
Self::new()
}
}
impl FallacyDatabase {
pub fn new() -> Self {
Self {
version: "2.0.0".to_string(),
fallacies: Self::initialize_fallacies(),
}
}
fn initialize_fallacies() -> Vec<FallacyDefinition> {
vec![
FallacyDefinition {
fallacy_type: "Ad Hominem".to_string(),
patterns: vec![
r#"attacking the person rather than the argument"#.to_string(),
r#"instead of addressing the argument, you attack the person"#.to_string(),
],
description: "Attacking the person making the argument rather than the argument itself".to_string(),
severity: "High".to_string(),
},
FallacyDefinition {
fallacy_type: "Straw Man".to_string(),
patterns: vec![
r#"misrepresenting someone's argument to make it easier to attack"#.to_string(),
r#"oversimplifying or exaggerating a position to make it easier to refute"#.to_string(),
],
description: "Misrepresenting someone's argument to make it easier to attack".to_string(),
severity: "High".to_string(),
},
FallacyDefinition {
fallacy_type: "False Dichotomy".to_string(),
patterns: vec![
r#"presenting two choices as the only options when more exist"#.to_string(),
r#"either.*or.*".to_string(),
],
description: "Presenting two choices as the only options when more possibilities exist".to_string(),
severity: "Medium".to_string(),
},
FallacyDefinition {
fallacy_type: "Appeal to Authority".to_string(),
patterns: vec![
r#"using the opinion of an authority figure as evidence"#.to_string(),
r#"because.*said so"#.to_string(),
],
description: "Using the opinion of an authority figure as evidence instead of relevant evidence".to_string(),
severity: "Medium".to_string(),
},
FallacyDefinition {
fallacy_type: "Circular Reasoning".to_string(),
patterns: vec![
r#"the conclusion is included in the premise"#.to_string(),
r#"begging the question"#.to_string(),
],
description: "Using the conclusion as evidence for the premise".to_string(),
severity: "High".to_string(),
},
FallacyDefinition {
fallacy_type: "Hasty Generalization".to_string(),
patterns: vec![
r#"drawing a general conclusion from a small sample"#.to_string(),
r#"everyone who"#.to_string(),
r#"all.*are.*based on.*experience"#.to_string(),
],
description: "Drawing a general conclusion from insufficient evidence".to_string(),
severity: "Medium".to_string(),
},
FallacyDefinition {
fallacy_type: "Post Hoc".to_string(),
patterns: vec![
r#"assuming that because B comes after A, A caused B"#.to_string(),
r#"after.*therefore.*because of.*"#.to_string(),
],
description: "Assuming that because one event followed another, the first caused the second".to_string(),
severity: "Medium".to_string(),
},
]
}
pub async fn detect_fallacies(&self, text: &str) -> Result<Vec<DetectedFallacy>> {
let mut detected_fallacies = Vec::new();
let text_lower = text.to_lowercase();
for fallacy in &self.fallacies {
for pattern in &fallacy.patterns {
if text_lower.contains(&pattern.to_lowercase()) {
detected_fallacies.push(DetectedFallacy {
fallacy_type: fallacy.fallacy_type.clone(),
description: fallacy.description.clone(),
confidence: 0.8, location: "pattern_match".to_string(),
severity: fallacy.severity.clone(),
});
}
}
}
Ok(detected_fallacies)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FallacyDefinition {
pub fallacy_type: String,
pub patterns: Vec<String>,
pub description: String,
pub severity: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DetectedFallacy {
pub fallacy_type: String,
pub description: String,
pub confidence: f64,
pub location: String,
pub severity: String,
}
impl M2ThinkTool for EnhancedLaserLogic {
fn execute_with_m2(&self, input: &str, profile: ProfileType) -> Result<M2ThinkToolResult> {
if tokio::runtime::Handle::try_current().is_ok() {
return Err(crate::error::Error::M2ExecutionError(
"execute_with_m2 cannot be called from within a Tokio runtime".to_string(),
));
}
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()?;
rt.block_on(self.execute_m2_methodology(input, profile))
}
fn get_composite_constraints(&self) -> Vec<CompositeInstruction> {
self.composite_constraints.clone()
}
fn get_interleaved_pattern(&self) -> InterleavedProtocol {
self.interleaved_protocol.clone()
}
fn get_performance_target(&self) -> super::performance_monitor::PerformanceMetrics {
super::performance_monitor::PerformanceMetrics {
target_confidence: 0.95, max_processing_time_ms: 4000,
max_token_count: 1800,
target_cost_efficiency: 1.08,
target_cross_validation_score: 0.90,
..Default::default()
}
}
}
pub async fn execute_enhanced_laserlogic(
argument: &str,
profile: ProfileType,
) -> Result<M2ThinkToolResult> {
let thinktool = EnhancedLaserLogic::new();
execute_profile_based_thinktool(&thinktool, argument, profile).await
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_enhanced_laserlogic_creation() {
let laserlogic = EnhancedLaserLogic::new();
assert_eq!(laserlogic.module_id, "enhanced_laserlogic");
assert_eq!(laserlogic.version, "2.0.0-minimax");
assert_eq!(laserlogic.composite_constraints.len(), 4);
assert!(!laserlogic.fallacy_database.fallacies.is_empty());
}
#[test]
fn test_fallacy_database() {
let db = FallacyDatabase::new();
assert!(!db.fallacies.is_empty());
let test_text = "Everyone who drives a red car is a bad driver because John drives a red car and he's terrible.";
let detected = futures::executor::block_on(db.detect_fallacies(test_text)).unwrap();
assert!(detected
.iter()
.any(|f| f.fallacy_type == "Hasty Generalization"));
}
#[tokio::test]
async fn test_execution_with_balanced_profile() {
let laserlogic = EnhancedLaserLogic::new();
let result = laserlogic.execute_with_m2(
"All birds can fly. Penguins are birds. Therefore, penguins can fly.",
ProfileType::Balanced,
);
match result {
Ok(result) => {
assert_eq!(result.module, "enhanced_laserlogic");
assert!(result.confidence >= 0.8);
assert!(result.processing_time_ms > 0);
}
Err(e) => {
println!("Expected error in test: {:?}", e);
}
}
}
}