/**
* Command Handler Module
* Part of Phase 4c: Command Interface Standardization
* Logic-Thinking MCP Server
*/
import { LogicalSystem, Operation, InputFormat } from './types.js';
import {
createCommandError,
errorSuggestions,
exampleTemplates
} from './errorHandler.js';
import { logicCache } from './utils/cache.js';
// Standard command types
export type CommandType =
| 'help'
| 'listSystems'
| 'listOperations'
| 'listFallacies'
| 'showHistory'
| 'exportProof'
| 'showExamples'
| 'cacheStats'
| 'clearCache';
// Command parameter interface
export interface CommandParams {
[key: string]: any;
}
// Command interface
export interface Command {
type: CommandType;
parameters?: CommandParams;
}
// Standardized function parameter interface
export interface StandardParams {
system?: LogicalSystem;
operation?: Operation;
input?: string;
format?: InputFormat;
command?: Command;
additionalContext?: string;
}
// Help content for each command
export const commandHelp: Record<CommandType, {
description: string;
usage: string;
examples: string[];
parameters?: Record<string, string>;
}> = {
help: {
description: 'Display help information for commands and operations',
usage: 'help --topic=[command|system|operation]',
examples: [
'help --topic=validate',
'help --topic=propositional',
'help'
],
parameters: {
topic: 'Optional topic to get help for (command, system, or operation name)'
}
},
listSystems: {
description: 'List all available logical systems',
usage: 'listSystems',
examples: ['listSystems']
},
listOperations: {
description: 'List all available operations',
usage: 'listOperations',
examples: ['listOperations']
},
listFallacies: {
description: 'List common logical fallacies',
usage: 'listFallacies --system=[syllogistic|propositional|predicate|all]',
examples: [
'listFallacies',
'listFallacies --system=syllogistic'
],
parameters: {
system: 'Optional logical system to filter fallacies (default: all)'
}
},
showHistory: {
description: 'Show operation history for the current session',
usage: 'showHistory --limit=[number]',
examples: [
'showHistory',
'showHistory --limit=5'
],
parameters: {
limit: 'Maximum number of history items to show (default: 10)'
}
},
exportProof: {
description: 'Export a proof in a specific format',
usage: 'exportProof --format=[text|html|latex]',
examples: [
'exportProof --format=text',
'exportProof --format=latex'
],
parameters: {
format: 'Output format for the proof (default: text)'
}
},
showExamples: {
description: 'Show examples for a specific system or operation',
usage: 'showExamples --system=[system] --operation=[operation]',
examples: [
'showExamples --system=propositional',
'showExamples --operation=validate'
],
parameters: {
system: 'Logical system to show examples for',
operation: 'Operation to show examples for'
}
},
cacheStats: {
description: 'Show cache performance statistics',
usage: 'cacheStats',
examples: ['cacheStats']
},
clearCache: {
description: 'Clear all cached logic operations',
usage: 'clearCache',
examples: ['clearCache']
}
};
// Help content for logical systems
export const systemHelp: Record<LogicalSystem, {
description: string;
examples: string[];
operators?: Record<string, string>;
limitations?: string[];
}> = {
syllogistic: {
description: 'Syllogistic logic deals with categorical statements relating classes or categories. It uses quantifiers like "All", "Some", "No" to express relationships between terms.',
examples: [
'All humans are mortal. Socrates is a human. Therefore, Socrates is mortal.',
'No mammals are fish. All whales are mammals. Therefore, no whales are fish.'
],
operators: {
'All S are P': 'Universal affirmative (A)',
'No S are P': 'Universal negative (E)',
'Some S are P': 'Particular affirmative (I)',
'Some S are not P': 'Particular negative (O)'
},
limitations: [
'Only supports three terms per argument',
'Limited to categorical statements',
'Cannot handle complex relationships'
]
},
propositional: {
description: 'Propositional logic deals with propositions that are either true or false and logical connectives between them.',
examples: [
'If it rains, then the ground is wet. It is raining. Therefore, the ground is wet.',
'P → Q, P, therefore Q'
],
operators: {
'∧': 'Conjunction (AND)',
'∨': 'Disjunction (OR)',
'¬': 'Negation (NOT)',
'→': 'Implication (IF-THEN)',
'↔': 'Biconditional (IF AND ONLY IF)',
'⊕': 'Exclusive OR (XOR)'
},
limitations: [
'Cannot represent quantifiers like "all" or "some"',
'Cannot represent internal structure of propositions',
'Current implementation requires single-letter variables'
]
},
predicate: {
description: 'Predicate logic extends propositional logic by introducing quantifiers and predicates, allowing for more expressive statements.',
examples: [
'All humans are mortal. Socrates is a human. Therefore, Socrates is mortal.',
'∀x (Human(x) → Mortal(x)), Human(socrates), therefore Mortal(socrates)'
],
operators: {
'∀': 'Universal quantifier (FOR ALL)',
'∃': 'Existential quantifier (THERE EXISTS)',
'→': 'Implication',
'∧': 'Conjunction',
'∨': 'Disjunction',
'¬': 'Negation'
},
limitations: [
'More complex syntax than propositional logic',
'May require understanding of predicate notation',
'Limited to first-order logic in current implementation'
]
},
mathematical: {
description: 'Mathematical logic handles arithmetic, sequences, patterns, and equations.',
examples: [
'Find the next number in the sequence: 1, 2, 3, 4, 5',
'Solve the equation: x + 5 = 10',
'Is the sequence 1, 1, 2, 3, 5, 8 a Fibonacci sequence?'
],
operators: {
'+': 'Addition',
'-': 'Subtraction',
'*': 'Multiplication',
'/': 'Division',
'=': 'Equality',
'<': 'Less than',
'>': 'Greater than'
},
limitations: [
'Currently supports only simple equations',
'Limited to basic arithmetic operations',
'Pattern recognition only for common sequences'
]
},
auto: {
description: 'Auto-detection mode analyzes your input and selects the most appropriate logical system.',
examples: [
'All humans are mortal. Socrates is a human. Therefore, Socrates is mortal.',
'P → Q, P, therefore Q',
'1, 2, 3, 4, 5. What comes next?'
],
limitations: [
'May not always select the optimal system',
'Works best with clear, standard inputs',
'May require explicit system selection for complex inputs'
]
},
modal: {
description: 'Modal logic deals with necessity and possibility, expressing what must be true, what might be true, and what is possible.',
examples: [
'□P → P (what is necessary is actual)',
'□(P → Q), □P, therefore □Q',
'It is necessary that all bachelors are unmarried.'
],
operators: {
'□': 'Necessity (BOX - it is necessary that)',
'◇': 'Possibility (DIAMOND - it is possible that)',
'→': 'Implication',
'∧': 'Conjunction',
'∨': 'Disjunction',
'¬': 'Negation'
},
limitations: [
'Requires understanding of modal operators',
'Different modal systems (K, T, S4, S5) have different axioms',
'Can be computationally intensive for complex formulas'
]
},
temporal: {
description: 'Temporal logic deals with time and temporal relationships, expressing what holds at different points in time.',
examples: [
'G P (P holds globally/always)',
'F P (P holds eventually)',
'X P (P holds at the next time)',
'P U Q (P holds until Q becomes true)'
],
operators: {
'G': 'Globally/Always',
'F': 'Eventually/Finally',
'X': 'Next',
'U': 'Until',
'R': 'Release',
'W': 'Weak Until'
},
limitations: [
'Requires understanding of temporal operators',
'Computationally intensive for long traces',
'Limited to linear time logic'
]
},
fuzzy: {
description: 'Fuzzy logic handles degrees of truth rather than binary true/false, useful for imprecise concepts.',
examples: [
'temperature IS hot (with membership degree)',
'very hot AND somewhat cold',
'If temperature IS hot THEN fan_speed IS fast'
],
operators: {
'AND': 'Fuzzy conjunction (minimum)',
'OR': 'Fuzzy disjunction (maximum)',
'NOT': 'Fuzzy negation (1 - value)',
'IMPLIES': 'Fuzzy implication'
},
limitations: [
'Requires membership function definitions',
'Results are degrees between 0 and 1',
'May be unintuitive for binary thinkers'
]
},
deontic: {
description: 'Deontic logic deals with obligations, permissions, and prohibitions in normative reasoning.',
examples: [
'O(pay_taxes) (it is obligatory to pay taxes)',
'P(travel) (it is permitted to travel)',
'F(steal) (it is forbidden to steal)',
'OB(help|emergency) (help is obligatory given an emergency)'
],
operators: {
'O': 'Obligatory',
'P': 'Permitted',
'F': 'Forbidden',
'OB': 'Obligatory given',
'PM': 'Permitted given',
'IM': 'Impermissible'
},
limitations: [
'Abstract normative concepts',
'May have paradoxes in complex scenarios',
'Requires understanding of deontic principles'
]
},
smt: {
description: 'SMT (Satisfiability Modulo Theories) uses Z3 solver for constraint solving, optimization, and verification problems.',
examples: [
'Find x and y where x + y = 10 and x > 5',
'Maximize 2*x + 3*y subject to x + y <= 10, x >= 0, y >= 0',
'Solve the system: x + y + z = 6, 2*x - y + z = 1, x + 2*y - z = 3'
],
operators: {
'+, -, *, /': 'Arithmetic operations',
'==, !=, <, >, <=, >=': 'Comparisons',
'And, Or, Not': 'Boolean logic',
'ForAll, Exists': 'Quantifiers'
},
limitations: [
'Requires Z3 Python package installation',
'Complex constraints may timeout',
'Natural language parsing still in development'
]
},
probabilistic: {
description: 'Probabilistic logic handles uncertain reasoning via probabilistic logic programming, supporting Bayesian inference and decision analysis.',
examples: [
'What is the probability that it rains given clouds? 0.3::rain. 0.7::rain :- clouds.',
'P(flu|fever=true, cough=true) where flu has 10% base rate and causes fever 90% of the time',
'30% chance of rain. If it rains, there is an 80% chance the game is cancelled.'
],
operators: {
'::': 'Probability annotation (0.7::fact)',
':-': 'Probabilistic rule (head :- body)',
'P(X|Y)': 'Conditional probability',
'evidence': 'Observed facts'
},
limitations: [
'Simplified inference (full ProbLog not required)',
'Large programs may be computationally intensive',
'Best for discrete probabilistic models'
]
},
asp: {
description: 'Answer Set Programming (ASP) uses Clingo solver for combinatorial search, optimization, and constraint satisfaction problems via declarative logic programming.',
examples: [
'Color a graph with 3 colors: vertex(1..5). edge(1,2). edge(2,3). 1 {assign(X,C) : color(C)} 1 :- vertex(X). :- assign(X,C), assign(Y,C), edge(X,Y).',
'Solve 4-Queens: Place 4 queens on a 4x4 board so none attack each other',
'Schedule employees to shifts with constraints: minimize total cost while satisfying capacity and availability'
],
operators: {
':-': 'Rule implication (head :- body)',
'not': 'Default negation (closed world assumption)',
'{...}': 'Choice rule (nondeterministic choice)',
'#minimize/#maximize': 'Optimization directives',
'#count/#sum': 'Aggregate functions'
},
limitations: [
'Requires Clingo installation',
'Grounding can be slow for large domains',
'Best for finite, discrete search problems'
]
}
};
// Help content for operations
export const operationHelp: Record<Operation, {
description: string;
examples: string[];
supportedSystems: LogicalSystem[];
parameters?: Record<string, string>;
}> = {
validate: {
description: 'Check a logical argument for validity',
examples: [
'validate --system=syllogistic --input="All humans are mortal. Socrates is a human. Therefore, Socrates is mortal."',
'validate --system=propositional --input="P → Q, P, therefore Q"'
],
supportedSystems: ['syllogistic', 'propositional', 'predicate', 'mathematical', 'modal', 'temporal', 'fuzzy', 'deontic', 'auto'],
parameters: {
system: 'Logical system to use',
input: 'Logical argument to validate',
format: 'Input format (natural, symbolic, mixed)'
}
},
formalize: {
description: 'Convert natural language to formal logical notation',
examples: [
'formalize --system=predicate --input="All humans are mortal."',
'formalize --system=propositional --input="If it rains, the ground gets wet."'
],
supportedSystems: ['syllogistic', 'propositional', 'predicate', 'mathematical', 'modal', 'temporal', 'fuzzy', 'deontic', 'auto'],
parameters: {
system: 'Logical system to use',
input: 'Natural language to formalize',
format: 'Input format (typically natural)'
}
},
visualize: {
description: 'Create a visualization of logical relationships',
examples: [
'visualize --system=syllogistic --input="All humans are mortal. Socrates is a human. Therefore, Socrates is mortal."',
'visualize --system=propositional --input="P ∧ (Q ∨ R)"'
],
supportedSystems: ['syllogistic', 'propositional', 'predicate', 'mathematical', 'modal', 'temporal', 'fuzzy', 'deontic', 'auto'],
parameters: {
system: 'Logical system to use',
input: 'Logical statement to visualize',
format: 'Input format (natural, symbolic, mixed)'
}
},
solve: {
description: 'Find a solution or proof for a logical problem',
examples: [
'solve --system=propositional --input="P → Q, Q → R, show P → R"',
'solve --system=mathematical --input="x + 5 = 10"'
],
supportedSystems: ['syllogistic', 'propositional', 'predicate', 'mathematical', 'modal', 'temporal', 'fuzzy', 'deontic', 'auto'],
parameters: {
system: 'Logical system to use',
input: 'Problem to solve',
format: 'Input format (natural, symbolic, mixed)'
}
}
};
// Examples for each system-operation combination
export const exampleInputs: Record<string, string[]> = {
'syllogistic-validate': [
'All humans are mortal. Socrates is a human. Therefore, Socrates is mortal.',
'No fish are mammals. All sharks are fish. Therefore, no sharks are mammals.',
'All dogs are mammals. All mammals are animals. Therefore, all dogs are animals.'
],
'syllogistic-formalize': [
'All humans are mortal.',
'Some birds can fly.',
'No reptiles are mammals.'
],
'syllogistic-visualize': [
'All humans are mortal. Socrates is a human. Therefore, Socrates is mortal.',
'No fish are mammals. All sharks are fish. Therefore, no sharks are mammals.'
],
'syllogistic-solve': [
'All M are P. All S are M. Therefore, what can we conclude about S and P?',
'Some B are A. All B are C. What valid conclusion follows?'
],
'propositional-validate': [
'P → Q, P, therefore Q',
'P ∨ Q, ¬P, therefore Q',
'P → Q, Q → R, therefore P → R'
],
'propositional-formalize': [
'If it rains, then the ground is wet.',
'Either the battery is dead or the circuit is broken.',
'The alarm will sound if and only if the door is opened.'
],
'propositional-visualize': [
'P ∧ (Q ∨ R)',
'(P → Q) ∧ (Q → R)',
'¬(P ∧ Q) ↔ (¬P ∨ ¬Q)'
],
'propositional-solve': [
'P → Q, Q → R, show P → R',
'P ∨ Q, ¬P, show Q',
'P → Q, ¬Q, show ¬P'
],
'predicate-validate': [
'∀x (Human(x) → Mortal(x)), Human(socrates), therefore Mortal(socrates)',
'∀x (P(x) → Q(x)), ∀x P(x), therefore ∀x Q(x)',
'∃x P(x), ∀x (P(x) → Q(x)), therefore ∃x Q(x)'
],
'predicate-formalize': [
'All humans are mortal.',
'Some birds can fly.',
'For all x, if x is prime, then x is divisible only by 1 and itself.'
],
'predicate-visualize': [
'∀x (Human(x) → Mortal(x))',
'∃x (Bird(x) ∧ ¬CanFly(x))',
'∀x (P(x) → ∃y R(x, y))'
],
'predicate-solve': [
'∀x (P(x) → Q(x)), ∀x P(x), show ∀x Q(x)',
'∃x P(x), ∀x (P(x) → Q(x)), show ∃x Q(x)',
'∀x (P(x) → Q(x)), ∀x (Q(x) → R(x)), show ∀x (P(x) → R(x))'
],
'mathematical-validate': [
'1, 2, 3, 4, 5',
'1, 2, 4, 8, 16',
'x + 5 = 10'
],
'mathematical-formalize': [
'Find the next number in the sequence: 1, 2, 3, 4, 5',
'Solve for x: x + 5 = 10',
'Determine if the sequence 1, 1, 2, 3, 5, 8 is a Fibonacci sequence'
],
'mathematical-visualize': [
'1, 2, 3, 4, 5',
'1, 2, 4, 8, 16',
'x + 5 = 10'
],
'mathematical-solve': [
'x + 5 = 10',
'Find the next number in the sequence: 1, 2, 3, 4, 5',
'What comes after 1, 1, 2, 3, 5, 8?'
],
'modal-validate': [
'□P → P',
'□(P → Q), □P, therefore □Q',
'◇P → □◇P'
],
'modal-formalize': [
'It is necessary that all bachelors are unmarried.',
'It is possible that it will rain tomorrow.',
'If something is necessary, then it is actual.'
],
'modal-visualize': [
'□P → P',
'□(P ∧ Q) → (□P ∧ □Q)',
'◇(P ∨ Q) ↔ (◇P ∨ ◇Q)'
],
'modal-solve': [
'□(P → Q), □P, show □Q',
'□P → P, P → Q, show □P → Q',
'◇P, □(P → Q), show ◇Q'
],
'temporal-validate': [
'G p',
'F p',
'p U q',
'G (p → F q)'
],
'temporal-formalize': [
'It always rains in April',
'Eventually the sun will shine',
'The light stays on until the switch is pressed',
'Next, the alarm will sound'
],
'temporal-visualize': [
'G p',
'F (p ∧ q)',
'p U q',
'G (request → F response)'
],
'temporal-solve': [
'G (p → q), G p, show G q',
'p U q, show F q',
'G p, show X p'
],
'fuzzy-validate': [
'temperature IS hot',
'very hot AND somewhat cold',
'hot(0.8)',
'IF temperature IS hot THEN fan_speed IS fast'
],
'fuzzy-formalize': [
'The weather is very hot',
'The car is somewhat fast',
'If temperature is high then cooling is needed'
],
'fuzzy-visualize': [
'hot',
'very tall',
'temperature IS warm',
'speed IS moderate'
],
'fuzzy-solve': [
'temperature IS hot, hot IMPLIES fast_fan',
'very hot OR slightly cold',
'IF height IS tall THEN reach IS high'
],
'deontic-validate': [
'O(pay_taxes)',
'P(travel)',
'F(steal)',
'O(help) → P(help)'
],
'deontic-formalize': [
'It is obligatory to pay taxes',
'Travel is permitted',
'Stealing is forbidden',
'If help is required, then helping is obligatory'
],
'deontic-visualize': [
'O(follow_laws)',
'P(express_opinion)',
'F(harm_others)',
'OB(help|emergency)'
],
'deontic-solve': [
'O(p) → P(p), O(pay_taxes), show P(pay_taxes)',
'F(p) ↔ O(¬p), F(steal), show O(¬steal)',
'O(p ∨ q), ¬P(p), show O(q)'
],
'smt-validate': [
'Find x and y where x + y = 10 and x > 5',
'Can x be both greater than 10 and less than 5?',
'x + y <= 100, x >= 0, y >= 0'
],
'smt-formalize': [
'Maximize profit where profit is 2*x + 3*y subject to x + y <= 10',
'Solve for integers x, y, z where x + y + z = 6',
'Find real numbers satisfying x^2 - 4*x + 3 = 0'
],
'smt-visualize': [
'x > 0, y > 0, x + y == 10, x > y',
'constraints: x + y <= 10, 2*x + y <= 15, x >= 0, y >= 0',
'system: x + y + z = 6, 2*x - y + z = 1, x + 2*y - z = 3'
],
'smt-solve': [
'Find x where x is greater than 0, x is less than 10, and x + 5 = 8',
'Maximize 2*x + 3*y where x + y <= 10 and x >= 0 and y >= 0',
'Solve: x + y + z = 6, 2*x - y + z = 1, x + 2*y - z = 3'
],
'probabilistic-validate': [
'0.3::rain. 0.7::rain :- clouds.',
'P(flu|fever) with 0.1::flu and 0.9::fever :- flu.',
'30% chance of rain. If it rains, 80% chance the game is cancelled.'
],
'probabilistic-formalize': [
'There is a 30% chance it rains. If it rains, there is an 80% chance the game is cancelled.',
'The probability of flu is 10%. If someone has flu, they have fever with 90% probability.',
'Rain is likely (70% chance) given clouds. Clouds occur with 50% probability.'
],
'probabilistic-visualize': [
'0.3::rain. 0.7::rain :- clouds. 0.5::clouds.',
'0.1::flu. 0.9::fever :- flu. 0.2::fever :- cold. 0.3::cold.',
'0.7::burglary. 0.2::earthquake. alarm :- burglary. alarm :- earthquake.'
],
'probabilistic-solve': [
'What is the probability of rain given clouds? 0.3::rain. 0.7::rain :- clouds. 0.5::clouds.',
'P(alarm|burglary=true) where 0.01::burglary and 0.95::alarm :- burglary.',
'Compute P(disease|symptom1=true, symptom2=true) with 0.01::disease, 0.8::symptom1 :- disease, 0.9::symptom2 :- disease.'
]
};
/**
* Validate a command and provide helpful feedback
* @param command The command to validate
* @returns Validation result
*/
export function validateCommand(command: Partial<Command>): {
isValid: boolean;
corrections?: string[];
help?: string;
} {
// Check if command type is provided
if (!command.type) {
return {
isValid: false,
help: 'Command type is required. Use "help" to see available commands.'
};
}
// Check if command type is valid
const validCommandTypes = Object.keys(commandHelp) as CommandType[];
if (!validCommandTypes.includes(command.type as CommandType)) {
// Try to find similar commands for suggestions
const suggestions = findSimilarCommands(command.type);
return {
isValid: false,
corrections: suggestions,
help: `Unknown command: ${command.type}. Did you mean: ${suggestions.join(', ')}?`
};
}
// Command type is valid, check parameters if needed
const cmd = command.type as CommandType;
const helpInfo = commandHelp[cmd];
// If command has required parameters, check them
if (helpInfo.parameters && command.parameters) {
const missingParams: string[] = [];
for (const [param, desc] of Object.entries(helpInfo.parameters)) {
// Only check for required parameters (those without "optional" in description)
if (!desc.toLowerCase().includes('optional') && !command.parameters[param]) {
missingParams.push(param);
}
}
if (missingParams.length > 0) {
return {
isValid: false,
help: `Missing required parameters: ${missingParams.join(', ')}.
Usage: ${helpInfo.usage}`
};
}
}
// Command is valid
return { isValid: true };
}
/**
* Find similar commands based on string similarity
* @param input User input command
* @returns Array of similar command suggestions
*/
function findSimilarCommands(input: string): string[] {
const validCommands = Object.keys(commandHelp);
const threshold = 0.4; // Similarity threshold
// Calculate similarity scores
const suggestions = validCommands
.map(cmd => ({
command: cmd,
similarity: calculateSimilarity(input, cmd)
}))
.filter(item => item.similarity > threshold)
.sort((a, b) => b.similarity - a.similarity)
.map(item => item.command);
// Return top 3 suggestions or fewer if not available
return suggestions.slice(0, 3);
}
/**
* Calculate string similarity score (0-1)
* @param a First string
* @param b Second string
* @returns Similarity score (0-1)
*/
function calculateSimilarity(a: string, b: string): number {
if (a === b) return 1.0;
if (a.length === 0 || b.length === 0) return 0.0;
// Simple levenshtein distance
const distance = levenshteinDistance(a.toLowerCase(), b.toLowerCase());
const maxLength = Math.max(a.length, b.length);
return 1 - distance / maxLength;
}
/**
* Calculate Levenshtein distance between two strings
* @param a First string
* @param b Second string
* @returns Levenshtein distance
*/
function levenshteinDistance(a: string, b: string): number {
const matrix: number[][] = [];
// Initialize matrix
for (let i = 0; i <= b.length; i++) {
matrix[i] = [i];
}
for (let j = 0; j <= a.length; j++) {
matrix[0][j] = j;
}
// Fill matrix
for (let i = 1; i <= b.length; i++) {
for (let j = 1; j <= a.length; j++) {
const cost = a[j - 1] === b[i - 1] ? 0 : 1;
matrix[i][j] = Math.min(
matrix[i - 1][j] + 1, // Deletion
matrix[i][j - 1] + 1, // Insertion
matrix[i - 1][j - 1] + cost // Substitution
);
}
}
return matrix[b.length][a.length];
}
/**
* Process a command and return the result
* @param params The command parameters
* @returns Command result
*/
export function processCommand(params: StandardParams): any {
const { command } = params;
if (!command) {
throw createCommandError(
'auto',
'Missing command',
'Provide a valid command object',
'command: { type: "help" }'
);
}
// Validate the command
const validationResult = validateCommand(command);
if (!validationResult.isValid) {
throw createCommandError(
'auto',
validationResult.help || 'Invalid command',
validationResult.corrections
? `Did you mean: ${validationResult.corrections.join(', ')}?`
: 'Check command syntax and parameters',
commandHelp[command.type as CommandType]?.examples[0] || 'help'
);
}
// Process different command types
switch (command.type) {
case 'help':
return generateHelp(command.parameters?.topic);
case 'listSystems':
return listSystems();
case 'listOperations':
return listOperations();
case 'listFallacies':
return listFallacies(command.parameters?.system);
case 'showHistory':
return showHistory(command.parameters?.limit);
case 'exportProof':
return exportProof(command.parameters?.format);
case 'showExamples':
return showExamples(command.parameters?.system, command.parameters?.operation);
case 'cacheStats':
return getCacheStats();
case 'clearCache':
return clearCache();
default:
throw createCommandError(
'auto',
`Unsupported command: ${command.type}`,
'Use a supported command type',
'help'
);
}
}
/**
* Generate help content
* @param topic Optional topic to get help for
* @returns Help content
*/
function generateHelp(topic?: string): any {
// If no topic is specified, show general help
if (!topic) {
// Generate general help content
return {
title: 'Logic-Thinking MCP Server Help',
sections: [
{
heading: 'Available Commands',
content: Object.entries(commandHelp).map(([cmd, info]) =>
`- ${cmd}: ${info.description}`
).join('\n')
},
{
heading: 'Logical Systems',
content: Object.entries(systemHelp).map(([sys, info]) =>
`- ${sys}: ${info.description.split('.')[0]}.`
).join('\n')
},
{
heading: 'Operations',
content: Object.entries(operationHelp).map(([op, info]) =>
`- ${op}: ${info.description}`
).join('\n')
},
{
heading: 'Getting Started',
content: 'Use "help --topic=[command|system|operation]" for detailed help on a specific topic.'
}
]
};
}
// Check if the topic is a command
if (topic in commandHelp) {
const cmdHelp = commandHelp[topic as CommandType];
return {
title: `Command: ${topic}`,
description: cmdHelp.description,
usage: cmdHelp.usage,
examples: cmdHelp.examples,
parameters: cmdHelp.parameters
};
}
// Check if the topic is a system
if (topic in systemHelp) {
const sysHelp = systemHelp[topic as LogicalSystem];
return {
title: `Logical System: ${topic}`,
description: sysHelp.description,
examples: sysHelp.examples,
operators: sysHelp.operators,
limitations: sysHelp.limitations
};
}
// Check if the topic is an operation
if (topic in operationHelp) {
const opHelp = operationHelp[topic as Operation];
return {
title: `Operation: ${topic}`,
description: opHelp.description,
examples: opHelp.examples,
supportedSystems: opHelp.supportedSystems,
parameters: opHelp.parameters
};
}
// Topic not found, try to find similar topics
const allTopics = [
...Object.keys(commandHelp),
...Object.keys(systemHelp),
...Object.keys(operationHelp)
];
const suggestions = allTopics
.map(t => ({
topic: t,
similarity: calculateSimilarity(topic, t)
}))
.filter(item => item.similarity > 0.4)
.sort((a, b) => b.similarity - a.similarity)
.slice(0, 3)
.map(item => item.topic);
// Return not found message with suggestions
return {
title: 'Topic Not Found',
message: `Topic "${topic}" not found.`,
suggestions: suggestions.length > 0
? `Did you mean: ${suggestions.join(', ')}?`
: 'Use "help" for a list of available topics.'
};
}
/**
* List all available logical systems
* @returns List of logical systems with descriptions
*/
function listSystems(): any {
return {
systems: Object.entries(systemHelp).map(([system, info]) => ({
name: system,
description: info.description.split('.')[0]
}))
};
}
/**
* List all available operations
* @returns List of operations with descriptions
*/
function listOperations(): any {
return {
operations: Object.entries(operationHelp).map(([operation, info]) => ({
name: operation,
description: info.description
}))
};
}
/**
* List logical fallacies
* @param system Optional logical system to filter fallacies
* @returns List of fallacies
*/
function listFallacies(system?: string): any {
// Define fallacies for each system
const fallacies = {
syllogistic: [
{
name: "Fallacy of Four Terms",
description: "Using more than three terms in a syllogism",
example: "All dogs are mammals. All cats have tails. Therefore, dogs have tails."
},
{
name: "Fallacy of Exclusive Premises",
description: "Invalid argument where both premises are negative",
example: "No dogs are cats. No cats are birds. Therefore, no dogs are birds."
},
{
name: "Fallacy of Undistributed Middle",
description: "The middle term is not distributed in either premise",
example: "All dogs are mammals. All cats are mammals. Therefore, all dogs are cats."
},
{
name: "Illicit Process",
description: "A term is distributed in the conclusion but not in the premises",
example: "All dogs are mammals. No cats are dogs. Therefore, no cats are mammals."
}
],
propositional: [
{
name: "Affirming the Consequent",
description: "Invalid argument of the form: (P→Q, Q, therefore P)",
example: "If it rains, the ground is wet. The ground is wet. Therefore, it rained."
},
{
name: "Denying the Antecedent",
description: "Invalid argument of the form: (P→Q, ¬P, therefore ¬Q)",
example: "If it rains, the ground is wet. It's not raining. Therefore, the ground is not wet."
},
{
name: "Fallacy of Composition",
description: "Assuming that what is true of the parts is true of the whole",
example: "Every atom in this chair is invisible. Therefore, the chair is invisible."
},
{
name: "False Dilemma",
description: "Presenting only two options when more exist",
example: "Either you're with us or against us."
}
],
predicate: [
{
name: "Quantifier Shift",
description: "Incorrectly moving quantifiers in an expression",
example: "∀x∃y(P(x,y)) ≠ ∃y∀x(P(x,y))"
},
{
name: "Existential Fallacy",
description: "Inferring existence from universal statements",
example: "All unicorns are white. Therefore, something white exists."
},
{
name: "Scope Confusion",
description: "Misinterpreting the scope of quantifiers",
example: "Everyone loves someone. Therefore, someone is loved by everyone."
}
],
mathematical: [
{
name: "Division by Zero",
description: "Attempting to divide by zero",
example: "x = 5/0"
},
{
name: "False Pattern Recognition",
description: "Finding patterns in random or insufficient data",
example: "1, 2, 4 is the start of a geometric sequence (it could also be other patterns)"
},
{
name: "Insufficient Constraint",
description: "Problem with multiple solutions due to insufficient constraints",
example: "Find x where x > 5"
}
]
};
// If a system is specified, return fallacies for that system
if (system && system !== 'all' && system in fallacies) {
return {
system,
fallacies: fallacies[system as keyof typeof fallacies]
};
}
// Otherwise, return all fallacies
return {
fallacies: Object.entries(fallacies).map(([sys, list]) => ({
system: sys,
fallacies: list
}))
};
}
/**
* Show operation history
* @param limit Maximum number of history items to show
* @returns Operation history
*/
function showHistory(limit?: number): any {
// This is a placeholder; real implementation would track history
return {
message: "History functionality is not yet implemented.",
note: "This feature will be available in a future update."
};
}
/**
* Export a proof in a specific format
* @param format Output format for the proof
* @returns Exported proof
*/
function exportProof(format: string = 'text'): any {
// This is a placeholder; real implementation would export actual proof
return {
message: "Proof export is not yet implemented.",
requestedFormat: format,
note: "This feature will be available in a future update."
};
}
/**
* Show examples for a specific system or operation
* @param system Logical system to show examples for
* @param operation Operation to show examples for
* @returns Examples
*/
function showExamples(system?: string, operation?: string): any {
// If both system and operation are specified, return specific examples
if (system && operation) {
const key = `${system}-${operation}`;
if (key in exampleInputs) {
return {
system,
operation,
examples: exampleInputs[key]
};
}
}
// If only system is specified, return examples for all operations
if (system) {
const results: { operation: string; examples: string[] }[] = [];
for (const [key, examples] of Object.entries(exampleInputs)) {
if (key.startsWith(`${system}-`)) {
const op = key.split('-')[1];
results.push({ operation: op, examples });
}
}
if (results.length > 0) {
return {
system,
operationExamples: results
};
}
}
// If only operation is specified, return examples for all systems
if (operation) {
const results: { system: string; examples: string[] }[] = [];
for (const [key, examples] of Object.entries(exampleInputs)) {
if (key.endsWith(`-${operation}`)) {
const sys = key.split('-')[0];
results.push({ system: sys, examples });
}
}
if (results.length > 0) {
return {
operation,
systemExamples: results
};
}
}
// If neither is specified, return a sampling of examples
return {
examples: Object.entries(exampleInputs).map(([key, examples]) => {
const [sys, op] = key.split('-');
return {
system: sys,
operation: op,
examples: examples.slice(0, 1) // Just the first example
};
})
};
}
/**
* Get cache statistics
* @returns Cache statistics
*/
function getCacheStats(): any {
const stats = logicCache.getStats();
const info = logicCache.getInfo();
return {
title: 'Cache Performance Statistics',
statistics: {
hits: stats.hits,
misses: stats.misses,
hitRate: `${(stats.hitRate * 100).toFixed(2)}%`,
totalRequests: stats.hits + stats.misses,
cachedEntries: stats.keys,
estimatedMemoryUsage: `${(info.memoryUsage / 1024).toFixed(2)} KB`
},
performance: {
cacheEffectiveness: stats.hitRate >= 0.5 ? 'Good' : stats.hitRate >= 0.2 ? 'Moderate' : 'Low',
recommendation: stats.hitRate < 0.2
? 'Cache hit rate is low. Consider if queries are too varied.'
: stats.hitRate > 0.8
? 'Excellent cache utilization!'
: 'Cache is providing moderate performance benefits.'
}
};
}
/**
* Clear the cache
* @returns Clear cache result
*/
function clearCache(): any {
const statsBeforeClear = logicCache.getStats();
logicCache.flush();
return {
title: 'Cache Cleared',
message: 'All cached logic operations have been cleared.',
clearedEntries: statsBeforeClear.keys,
previousHitRate: `${(statsBeforeClear.hitRate * 100).toFixed(2)}%`
};
}