1use crate::error::QuantRS2Error;
8use crate::gate_translation::GateType;
9use crate::scirs2_quantum_linter::{LintSeverity, LintingConfig, QuantumGate};
10use scirs2_core::Complex64;
11use crate::parallel_ops_stubs::*;
13use crate::buffer_pool::BufferPool;
15use crate::platform::PlatformCapabilities;
16use scirs2_core::ndarray::{Array1, Array2};
17use serde::{Deserialize, Serialize};
18use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
19use std::fmt;
20use std::sync::{Arc, Mutex};
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct EnhancedLintingConfig {
25 pub base_config: LintingConfig,
27
28 pub enable_ml_pattern_detection: bool,
30
31 pub enable_algorithm_recognition: bool,
33
34 pub enable_complexity_analysis: bool,
36
37 pub enable_noise_resilience_check: bool,
39
40 pub enable_topological_optimization: bool,
42
43 pub enable_qec_pattern_detection: bool,
45
46 pub enable_cross_compilation_check: bool,
48
49 pub enable_hardware_specific_linting: bool,
51
52 pub target_architectures: Vec<HardwareArchitecture>,
54
55 pub pattern_database_version: String,
57
58 pub max_analysis_depth: usize,
60
61 pub enable_incremental_linting: bool,
63
64 pub custom_rules: Vec<CustomLintRule>,
66
67 pub report_format: ReportFormat,
69}
70
71impl Default for EnhancedLintingConfig {
72 fn default() -> Self {
73 Self {
74 base_config: LintingConfig::default(),
75 enable_ml_pattern_detection: true,
76 enable_algorithm_recognition: true,
77 enable_complexity_analysis: true,
78 enable_noise_resilience_check: true,
79 enable_topological_optimization: true,
80 enable_qec_pattern_detection: true,
81 enable_cross_compilation_check: true,
82 enable_hardware_specific_linting: true,
83 target_architectures: vec![
84 HardwareArchitecture::IBMQ,
85 HardwareArchitecture::IonQ,
86 HardwareArchitecture::Simulator,
87 ],
88 pattern_database_version: "1.0.0".to_string(),
89 max_analysis_depth: 1000,
90 enable_incremental_linting: true,
91 custom_rules: Vec::new(),
92 report_format: ReportFormat::Detailed,
93 }
94 }
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
99pub enum HardwareArchitecture {
100 IBMQ,
101 IonQ,
102 Rigetti,
103 GoogleSycamore,
104 Honeywell,
105 AWSBraket,
106 Simulator,
107 Custom,
108}
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
112pub enum ReportFormat {
113 Summary,
114 Detailed,
115 JSON,
116 SARIF,
117 HTML,
118 Markdown,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct CustomLintRule {
124 pub name: String,
125 pub description: String,
126 pub pattern: LintPattern,
127 pub severity: LintSeverity,
128 pub fix_suggestion: Option<String>,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
133pub enum LintPattern {
134 GateSequence(Vec<GatePatternMatcher>),
136 StructuralPattern(StructuralMatcher),
138 ResourcePattern(ResourceMatcher),
140 CustomPattern(String),
142}
143
144#[derive(Debug, Clone, Serialize, Deserialize)]
145pub struct GatePatternMatcher {
146 pub gate_type: Option<GateType>,
147 pub qubit_count: Option<usize>,
148 pub is_controlled: Option<bool>,
149 pub is_parameterized: Option<bool>,
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize)]
153pub struct StructuralMatcher {
154 pub min_depth: Option<usize>,
155 pub max_depth: Option<usize>,
156 pub has_loops: Option<bool>,
157 pub has_measurements: Option<bool>,
158}
159
160#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct ResourceMatcher {
162 pub min_qubits: Option<usize>,
163 pub max_qubits: Option<usize>,
164 pub min_gates: Option<usize>,
165 pub max_gates: Option<usize>,
166}
167
168#[derive(Debug, Clone, Serialize, Deserialize)]
170pub struct EnhancedLintFinding {
171 pub finding_type: LintFindingType,
172 pub severity: LintSeverity,
173 pub location: CircuitLocation,
174 pub message: String,
175 pub explanation: String,
176 pub impact: ImpactAnalysis,
177 pub fix_suggestions: Vec<FixSuggestion>,
178 pub related_findings: Vec<usize>,
179 pub confidence: f64,
180 pub references: Vec<String>,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct CircuitLocation {
185 pub gate_indices: Vec<usize>,
186 pub qubit_indices: Vec<usize>,
187 pub layer: Option<usize>,
188 pub subcircuit: Option<String>,
189}
190
191#[derive(Debug, Clone, Serialize, Deserialize)]
192pub struct ImpactAnalysis {
193 pub performance_impact: PerformanceImpact,
194 pub error_impact: f64,
195 pub resource_impact: ResourceImpact,
196 pub hardware_compatibility: Vec<(HardwareArchitecture, Compatibility)>,
197}
198
199#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
200pub enum PerformanceImpact {
201 Negligible,
202 Low,
203 Medium,
204 High,
205 Critical,
206}
207
208#[derive(Debug, Clone, Serialize, Deserialize)]
209pub struct ResourceImpact {
210 pub additional_gates: i32,
211 pub additional_qubits: i32,
212 pub depth_increase: i32,
213 pub memory_overhead: f64,
214}
215
216#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
217pub enum Compatibility {
218 FullyCompatible,
219 PartiallyCompatible,
220 RequiresTranspilation,
221 Incompatible,
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize)]
225pub struct FixSuggestion {
226 pub description: String,
227 pub automatic: bool,
228 pub code_changes: Vec<CodeChange>,
229 pub estimated_improvement: f64,
230 pub risk_level: RiskLevel,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
234pub struct CodeChange {
235 pub operation: ChangeOperation,
236 pub location: CircuitLocation,
237 pub new_gates: Option<Vec<QuantumGate>>,
238}
239
240#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
241pub enum ChangeOperation {
242 Replace,
243 Insert,
244 Delete,
245 Reorder,
246 Merge,
247}
248
249#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
250pub enum RiskLevel {
251 Safe,
252 Low,
253 Medium,
254 High,
255}
256
257#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
259pub enum LintFindingType {
260 RedundantGates,
262 InefficientDecomposition,
263 MissedFusionOpportunity,
264 SuboptimalGateOrder,
265 ExcessiveCircuitDepth,
266
267 QuantumAntiPattern,
269 UnnecessaryMeasurement,
270 EntanglementLeak,
271 CoherenceViolation,
272
273 MissingErrorMitigation,
275 PoorQubitAllocation,
276 InadequateParameterization,
277 LackOfModularity,
278
279 UnsupportedGateSet,
281 ConnectivityViolation,
282 ExceedsCoherenceTime,
283 CalibrationMismatch,
284
285 IncorrectAlgorithmImplementation,
287 SuboptimalAlgorithmChoice,
288 MissingAncillaQubits,
289
290 ExcessiveQubitUsage,
292 MemoryInefficiency,
293 ParallelizationOpportunity,
294
295 NumericalInstability,
297 PrecisionLoss,
298 PhaseAccumulation,
299
300 CustomRule(String),
302}
303
304impl fmt::Display for LintFindingType {
305 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
306 match self {
307 Self::RedundantGates => write!(f, "Redundant Gates"),
308 Self::InefficientDecomposition => write!(f, "Inefficient Decomposition"),
309 Self::MissedFusionOpportunity => write!(f, "Missed Fusion Opportunity"),
310 Self::SuboptimalGateOrder => write!(f, "Suboptimal Gate Order"),
311 Self::ExcessiveCircuitDepth => write!(f, "Excessive Circuit Depth"),
312 Self::QuantumAntiPattern => write!(f, "Quantum Anti-Pattern"),
313 Self::UnnecessaryMeasurement => write!(f, "Unnecessary Measurement"),
314 Self::EntanglementLeak => write!(f, "Entanglement Leak"),
315 Self::CoherenceViolation => write!(f, "Coherence Violation"),
316 Self::MissingErrorMitigation => write!(f, "Missing Error Mitigation"),
317 Self::PoorQubitAllocation => write!(f, "Poor Qubit Allocation"),
318 Self::InadequateParameterization => write!(f, "Inadequate Parameterization"),
319 Self::LackOfModularity => write!(f, "Lack of Modularity"),
320 Self::UnsupportedGateSet => write!(f, "Unsupported Gate Set"),
321 Self::ConnectivityViolation => write!(f, "Connectivity Violation"),
322 Self::ExceedsCoherenceTime => write!(f, "Exceeds Coherence Time"),
323 Self::CalibrationMismatch => write!(f, "Calibration Mismatch"),
324 Self::IncorrectAlgorithmImplementation => {
325 write!(f, "Incorrect Algorithm Implementation")
326 }
327 Self::SuboptimalAlgorithmChoice => write!(f, "Suboptimal Algorithm Choice"),
328 Self::MissingAncillaQubits => write!(f, "Missing Ancilla Qubits"),
329 Self::ExcessiveQubitUsage => write!(f, "Excessive Qubit Usage"),
330 Self::MemoryInefficiency => write!(f, "Memory Inefficiency"),
331 Self::ParallelizationOpportunity => write!(f, "Parallelization Opportunity"),
332 Self::NumericalInstability => write!(f, "Numerical Instability"),
333 Self::PrecisionLoss => write!(f, "Precision Loss"),
334 Self::PhaseAccumulation => write!(f, "Phase Accumulation"),
335 Self::CustomRule(name) => write!(f, "Custom Rule: {name}"),
336 }
337 }
338}
339
340struct PatternDatabase {
342 gate_patterns: HashMap<String, CompiledPattern>,
343 algorithm_signatures: HashMap<String, AlgorithmSignature>,
344 antipattern_library: Vec<AntiPattern>,
345 optimization_rules: Vec<OptimizationRule>,
346}
347
348struct CompiledPattern {
349 pattern_id: String,
350 matcher: Box<dyn Fn(&[QuantumGate]) -> bool + Send + Sync>,
351 min_length: usize,
352 max_length: usize,
353}
354
355#[derive(Debug, Clone)]
356struct AlgorithmSignature {
357 name: String,
358 gate_sequence: Vec<GateType>,
359 variations: Vec<Vec<GateType>>,
360 required_qubits: usize,
361}
362
363#[derive(Debug, Clone)]
364struct AntiPattern {
365 name: String,
366 description: String,
367 pattern: Vec<GatePatternMatcher>,
368 severity: LintSeverity,
369 fix_strategy: String,
370}
371
372struct OptimizationRule {
373 name: String,
374 condition: Box<dyn Fn(&[QuantumGate]) -> bool + Send + Sync>,
375 optimization: Box<dyn Fn(&[QuantumGate]) -> Vec<QuantumGate> + Send + Sync>,
376 improvement_estimate: f64,
377}
378
379struct MLPatternDetector {
381 model_type: MLModelType,
382 feature_extractor: FeatureExtractor,
383 pattern_classifier: PatternClassifier,
384 confidence_threshold: f64,
385}
386
387#[derive(Debug, Clone, Copy)]
388enum MLModelType {
389 NeuralNetwork,
390 DecisionTree,
391 SVM,
392 Ensemble,
393}
394
395struct FeatureExtractor {
396 feature_functions: Vec<Box<dyn Fn(&[QuantumGate]) -> Vec<f64> + Send + Sync>>,
397}
398
399struct PatternClassifier {
400 classify: Box<dyn Fn(&[f64]) -> (LintFindingType, f64) + Send + Sync>,
401}
402
403pub struct EnhancedQuantumLinter {
405 config: EnhancedLintingConfig,
406 platform_caps: PlatformCapabilities,
407 buffer_pool: Arc<BufferPool<Complex64>>,
408 pattern_database: Arc<PatternDatabase>,
409 ml_detector: Option<MLPatternDetector>,
410 cache: Arc<Mutex<LintCache>>,
411 statistics: Arc<Mutex<LintStatistics>>,
412}
413
414struct LintCache {
415 findings: HashMap<String, Vec<EnhancedLintFinding>>,
416 analyzed_patterns: HashSet<String>,
417}
418
419#[derive(Debug, Clone, Default, Serialize, Deserialize)]
420struct LintStatistics {
421 total_circuits_analyzed: usize,
422 total_findings: usize,
423 findings_by_type: HashMap<LintFindingType, usize>,
424 findings_by_severity: HashMap<LintSeverity, usize>,
425 average_analysis_time: std::time::Duration,
426 patterns_detected: HashMap<String, usize>,
427}
428
429impl EnhancedQuantumLinter {
430 pub fn new() -> Self {
432 Self::with_config(EnhancedLintingConfig::default())
433 }
434
435 pub fn with_config(config: EnhancedLintingConfig) -> Self {
437 let platform_caps = PlatformCapabilities::detect();
438 let buffer_pool = Arc::new(BufferPool::new());
439 let pattern_database = Arc::new(Self::build_pattern_database());
440
441 let ml_detector = if config.enable_ml_pattern_detection {
442 Some(Self::build_ml_detector())
443 } else {
444 None
445 };
446
447 Self {
448 config,
449 platform_caps,
450 buffer_pool,
451 pattern_database,
452 ml_detector,
453 cache: Arc::new(Mutex::new(LintCache {
454 findings: HashMap::new(),
455 analyzed_patterns: HashSet::new(),
456 })),
457 statistics: Arc::new(Mutex::new(LintStatistics::default())),
458 }
459 }
460
461 fn build_pattern_database() -> PatternDatabase {
463 let mut gate_patterns = HashMap::new();
464 let mut algorithm_signatures = HashMap::new();
465 let mut antipattern_library = Vec::new();
466 let mut optimization_rules = Vec::new();
467
468 gate_patterns.insert(
470 "double_hadamard".to_string(),
471 CompiledPattern {
472 pattern_id: "double_hadamard".to_string(),
473 matcher: Box::new(|gates| {
474 gates.windows(2).any(|window| {
475 matches!(window[0].gate_type(), GateType::H)
476 && matches!(window[1].gate_type(), GateType::H)
477 && window[0].target_qubits() == window[1].target_qubits()
478 })
479 }),
480 min_length: 2,
481 max_length: 2,
482 },
483 );
484
485 algorithm_signatures.insert(
487 "qft".to_string(),
488 AlgorithmSignature {
489 name: "Quantum Fourier Transform".to_string(),
490 gate_sequence: vec![GateType::H, GateType::Rz("0.0".to_string()), GateType::CNOT],
491 variations: vec![],
492 required_qubits: 2,
493 },
494 );
495
496 algorithm_signatures.insert(
497 "grover".to_string(),
498 AlgorithmSignature {
499 name: "Grover's Algorithm".to_string(),
500 gate_sequence: vec![GateType::H, GateType::X, GateType::Z, GateType::H],
501 variations: vec![],
502 required_qubits: 1,
503 },
504 );
505
506 antipattern_library.push(AntiPattern {
508 name: "Redundant Identity".to_string(),
509 description: "Gates that cancel each other out".to_string(),
510 pattern: vec![
511 GatePatternMatcher {
512 gate_type: Some(GateType::X),
513 qubit_count: None,
514 is_controlled: Some(false),
515 is_parameterized: Some(false),
516 },
517 GatePatternMatcher {
518 gate_type: Some(GateType::X),
519 qubit_count: None,
520 is_controlled: Some(false),
521 is_parameterized: Some(false),
522 },
523 ],
524 severity: LintSeverity::Warning,
525 fix_strategy: "Remove both gates".to_string(),
526 });
527
528 PatternDatabase {
529 gate_patterns,
530 algorithm_signatures,
531 antipattern_library,
532 optimization_rules,
533 }
534 }
535
536 fn build_ml_detector() -> MLPatternDetector {
538 let feature_extractor = FeatureExtractor {
539 feature_functions: vec![
540 Box::new(|gates| vec![gates.len() as f64]),
541 Box::new(|gates| {
542 let depth = Self::calculate_circuit_depth(gates);
543 vec![depth as f64]
544 }),
545 Box::new(|gates| {
546 let cnot_count = gates
547 .iter()
548 .filter(|g| matches!(g.gate_type(), GateType::CNOT))
549 .count();
550 vec![cnot_count as f64]
551 }),
552 ],
553 };
554
555 let pattern_classifier = PatternClassifier {
556 classify: Box::new(|features| {
557 if features[0] > 100.0 {
559 (LintFindingType::ExcessiveCircuitDepth, 0.8)
560 } else {
561 (LintFindingType::CustomRule("Unknown".to_string()), 0.5)
562 }
563 }),
564 };
565
566 MLPatternDetector {
567 model_type: MLModelType::Ensemble,
568 feature_extractor,
569 pattern_classifier,
570 confidence_threshold: 0.7,
571 }
572 }
573
574 pub fn lint_circuit(
576 &self,
577 circuit: &[QuantumGate],
578 circuit_metadata: Option<CircuitMetadata>,
579 ) -> Result<EnhancedLintingReport, QuantRS2Error> {
580 let start_time = std::time::Instant::now();
581
582 {
584 let mut stats = self
585 .statistics
586 .lock()
587 .map_err(|e| QuantRS2Error::LockPoisoned(format!("Statistics lock: {e}")))?;
588 stats.total_circuits_analyzed += 1;
589 }
590
591 let cache_key = self.compute_cache_key(circuit);
593 if self.config.enable_incremental_linting {
594 if let Some(cached_findings) = self.check_cache(&cache_key) {
595 return Ok(self.create_report(cached_findings, start_time.elapsed()));
596 }
597 }
598
599 let mut all_findings = Vec::new();
600
601 if self.config.base_config.detect_performance_issues {
603 all_findings.extend(self.detect_performance_issues(circuit)?);
604 }
605
606 if self.config.base_config.analyze_gate_patterns {
607 all_findings.extend(self.analyze_gate_patterns(circuit)?);
608 }
609
610 if self.config.base_config.detect_quantum_antipatterns {
611 all_findings.extend(self.detect_antipatterns(circuit)?);
612 }
613
614 if self.config.enable_algorithm_recognition {
615 all_findings.extend(self.recognize_algorithms(circuit)?);
616 }
617
618 if self.config.enable_complexity_analysis {
619 all_findings.extend(self.analyze_complexity(circuit)?);
620 }
621
622 if self.config.enable_noise_resilience_check {
623 all_findings.extend(self.check_noise_resilience(circuit)?);
624 }
625
626 if self.config.enable_hardware_specific_linting {
627 all_findings.extend(self.check_hardware_compatibility(circuit)?);
628 }
629
630 for custom_rule in &self.config.custom_rules {
632 all_findings.extend(self.apply_custom_rule(circuit, custom_rule)?);
633 }
634
635 if let Some(ref ml_detector) = self.ml_detector {
637 all_findings.extend(self.ml_pattern_detection(circuit, ml_detector)?);
638 }
639
640 all_findings.sort_by(|a, b| {
642 b.severity.cmp(&a.severity).then_with(|| {
643 let a_idx = a.location.gate_indices.first().copied().unwrap_or(0);
644 let b_idx = b.location.gate_indices.first().copied().unwrap_or(0);
645 a_idx.cmp(&b_idx)
646 })
647 });
648
649 let filtered_findings: Vec<_> = all_findings
651 .into_iter()
652 .filter(|f| f.severity >= self.config.base_config.severity_threshold)
653 .collect();
654
655 if self.config.enable_incremental_linting {
657 self.update_cache(cache_key, filtered_findings.clone());
658 }
659
660 self.update_statistics(&filtered_findings);
662
663 Ok(self.create_report(filtered_findings, start_time.elapsed()))
665 }
666
667 fn detect_performance_issues(
669 &self,
670 circuit: &[QuantumGate],
671 ) -> Result<Vec<EnhancedLintFinding>, QuantRS2Error> {
672 let mut findings = Vec::new();
673
674 for (i, window) in circuit.windows(2).enumerate() {
676 if Self::are_inverse_gates(&window[0], &window[1]) {
677 findings.push(EnhancedLintFinding {
678 finding_type: LintFindingType::RedundantGates,
679 severity: LintSeverity::Warning,
680 location: CircuitLocation {
681 gate_indices: vec![i, i + 1],
682 qubit_indices: window[0].target_qubits().to_vec(),
683 layer: None,
684 subcircuit: None,
685 },
686 message: "Redundant gate pair detected".to_string(),
687 explanation: format!(
688 "Gates {:?} and {:?} cancel each other out",
689 window[0].gate_type(),
690 window[1].gate_type()
691 ),
692 impact: ImpactAnalysis {
693 performance_impact: PerformanceImpact::Medium,
694 error_impact: 0.0,
695 resource_impact: ResourceImpact {
696 additional_gates: -2,
697 additional_qubits: 0,
698 depth_increase: -2,
699 memory_overhead: 0.0,
700 },
701 hardware_compatibility: vec![],
702 },
703 fix_suggestions: vec![FixSuggestion {
704 description: "Remove both gates".to_string(),
705 automatic: true,
706 code_changes: vec![CodeChange {
707 operation: ChangeOperation::Delete,
708 location: CircuitLocation {
709 gate_indices: vec![i, i + 1],
710 qubit_indices: vec![],
711 layer: None,
712 subcircuit: None,
713 },
714 new_gates: None,
715 }],
716 estimated_improvement: 0.1,
717 risk_level: RiskLevel::Safe,
718 }],
719 related_findings: vec![],
720 confidence: 1.0,
721 references: vec!["Quantum Circuit Optimization Guide".to_string()],
722 });
723 }
724 }
725
726 findings.extend(self.find_fusion_opportunities(circuit)?);
728
729 let depth = Self::calculate_circuit_depth(circuit);
731 if depth > 100 {
732 findings.push(EnhancedLintFinding {
733 finding_type: LintFindingType::ExcessiveCircuitDepth,
734 severity: LintSeverity::Warning,
735 location: CircuitLocation {
736 gate_indices: (0..circuit.len()).collect(),
737 qubit_indices: vec![],
738 layer: None,
739 subcircuit: None,
740 },
741 message: format!("Circuit depth {depth} exceeds recommended threshold"),
742 explanation: "Deep circuits are more susceptible to decoherence".to_string(),
743 impact: ImpactAnalysis {
744 performance_impact: PerformanceImpact::High,
745 error_impact: depth as f64 * 0.001,
746 resource_impact: ResourceImpact {
747 additional_gates: 0,
748 additional_qubits: 0,
749 depth_increase: 0,
750 memory_overhead: 0.0,
751 },
752 hardware_compatibility: vec![
753 (
754 HardwareArchitecture::IBMQ,
755 Compatibility::PartiallyCompatible,
756 ),
757 (
758 HardwareArchitecture::IonQ,
759 Compatibility::PartiallyCompatible,
760 ),
761 ],
762 },
763 fix_suggestions: vec![FixSuggestion {
764 description: "Consider circuit parallelization".to_string(),
765 automatic: false,
766 code_changes: vec![],
767 estimated_improvement: 0.3,
768 risk_level: RiskLevel::Medium,
769 }],
770 related_findings: vec![],
771 confidence: 0.9,
772 references: vec!["NISQ Algorithm Design".to_string()],
773 });
774 }
775
776 Ok(findings)
777 }
778
779 fn analyze_gate_patterns(
781 &self,
782 circuit: &[QuantumGate],
783 ) -> Result<Vec<EnhancedLintFinding>, QuantRS2Error> {
784 let mut findings = Vec::new();
785
786 for (pattern_id, compiled_pattern) in &self.pattern_database.gate_patterns {
788 if circuit.len() >= compiled_pattern.min_length {
789 for i in 0..=circuit.len().saturating_sub(compiled_pattern.min_length) {
790 let slice = &circuit[i..];
791 if (compiled_pattern.matcher)(slice) {
792 findings.push(self.create_pattern_finding(pattern_id, i, slice)?);
793 }
794 }
795 }
796 }
797
798 Ok(findings)
799 }
800
801 fn detect_antipatterns(
803 &self,
804 circuit: &[QuantumGate],
805 ) -> Result<Vec<EnhancedLintFinding>, QuantRS2Error> {
806 let mut findings = Vec::new();
807
808 for antipattern in &self.pattern_database.antipattern_library {
809 let pattern_len = antipattern.pattern.len();
810 if circuit.len() >= pattern_len {
811 for i in 0..=circuit.len() - pattern_len {
812 if Self::matches_pattern(&circuit[i..i + pattern_len], &antipattern.pattern) {
813 findings.push(EnhancedLintFinding {
814 finding_type: LintFindingType::QuantumAntiPattern,
815 severity: antipattern.severity.clone(),
816 location: CircuitLocation {
817 gate_indices: (i..i + pattern_len).collect(),
818 qubit_indices: vec![],
819 layer: None,
820 subcircuit: None,
821 },
822 message: format!("Anti-pattern detected: {}", antipattern.name),
823 explanation: antipattern.description.clone(),
824 impact: ImpactAnalysis {
825 performance_impact: PerformanceImpact::Medium,
826 error_impact: 0.05,
827 resource_impact: ResourceImpact {
828 additional_gates: 0,
829 additional_qubits: 0,
830 depth_increase: 0,
831 memory_overhead: 0.0,
832 },
833 hardware_compatibility: vec![],
834 },
835 fix_suggestions: vec![FixSuggestion {
836 description: antipattern.fix_strategy.clone(),
837 automatic: false,
838 code_changes: vec![],
839 estimated_improvement: 0.2,
840 risk_level: RiskLevel::Low,
841 }],
842 related_findings: vec![],
843 confidence: 0.95,
844 references: vec!["Quantum Programming Best Practices".to_string()],
845 });
846 }
847 }
848 }
849 }
850
851 Ok(findings)
852 }
853
854 fn recognize_algorithms(
856 &self,
857 circuit: &[QuantumGate],
858 ) -> Result<Vec<EnhancedLintFinding>, QuantRS2Error> {
859 let mut findings = Vec::new();
860
861 for (algo_name, signature) in &self.pattern_database.algorithm_signatures {
862 if let Some(match_location) = Self::find_algorithm_signature(circuit, signature) {
863 findings.push(EnhancedLintFinding {
864 finding_type: LintFindingType::CustomRule(format!("Algorithm: {algo_name}")),
865 severity: LintSeverity::Info,
866 location: CircuitLocation {
867 gate_indices: match_location,
868 qubit_indices: vec![],
869 layer: None,
870 subcircuit: None,
871 },
872 message: format!("Recognized algorithm: {}", signature.name),
873 explanation: "Standard quantum algorithm pattern detected".to_string(),
874 impact: ImpactAnalysis {
875 performance_impact: PerformanceImpact::Negligible,
876 error_impact: 0.0,
877 resource_impact: ResourceImpact {
878 additional_gates: 0,
879 additional_qubits: 0,
880 depth_increase: 0,
881 memory_overhead: 0.0,
882 },
883 hardware_compatibility: vec![],
884 },
885 fix_suggestions: vec![],
886 related_findings: vec![],
887 confidence: 0.8,
888 references: vec![format!("{} Implementation Guide", signature.name)],
889 });
890 }
891 }
892
893 Ok(findings)
894 }
895
896 fn analyze_complexity(
898 &self,
899 circuit: &[QuantumGate],
900 ) -> Result<Vec<EnhancedLintFinding>, QuantRS2Error> {
901 let mut findings = Vec::new();
902
903 let gate_count = circuit.len();
905 let depth = Self::calculate_circuit_depth(circuit);
906 let qubit_count = Self::count_qubits(circuit);
907 let cnot_count = circuit
908 .iter()
909 .filter(|g| matches!(g.gate_type(), GateType::CNOT))
910 .count();
911
912 let t_count = circuit
914 .iter()
915 .filter(|g| matches!(g.gate_type(), GateType::T))
916 .count();
917
918 if t_count > 50 {
920 findings.push(EnhancedLintFinding {
921 finding_type: LintFindingType::CustomRule("High T-count".to_string()),
922 severity: LintSeverity::Warning,
923 location: CircuitLocation {
924 gate_indices: vec![],
925 qubit_indices: vec![],
926 layer: None,
927 subcircuit: None,
928 },
929 message: format!("High T-gate count: {t_count}"),
930 explanation: "T-gates are expensive in fault-tolerant quantum computing"
931 .to_string(),
932 impact: ImpactAnalysis {
933 performance_impact: PerformanceImpact::High,
934 error_impact: t_count as f64 * 0.001,
935 resource_impact: ResourceImpact {
936 additional_gates: 0,
937 additional_qubits: 0,
938 depth_increase: 0,
939 memory_overhead: 0.0,
940 },
941 hardware_compatibility: vec![],
942 },
943 fix_suggestions: vec![FixSuggestion {
944 description: "Consider T-gate optimization techniques".to_string(),
945 automatic: false,
946 code_changes: vec![],
947 estimated_improvement: 0.3,
948 risk_level: RiskLevel::Medium,
949 }],
950 related_findings: vec![],
951 confidence: 1.0,
952 references: vec!["T-gate Optimization in Quantum Circuits".to_string()],
953 });
954 }
955
956 Ok(findings)
957 }
958
959 fn check_noise_resilience(
961 &self,
962 circuit: &[QuantumGate],
963 ) -> Result<Vec<EnhancedLintFinding>, QuantRS2Error> {
964 let mut findings = Vec::new();
965
966 let mut consecutive_gates = 0;
968 let mut last_check_index = 0;
969
970 for (i, gate) in circuit.iter().enumerate() {
971 consecutive_gates += 1;
972
973 if false {
976 consecutive_gates = 0;
977 last_check_index = i;
978 }
979
980 if consecutive_gates > 20 {
981 findings.push(EnhancedLintFinding {
982 finding_type: LintFindingType::MissingErrorMitigation,
983 severity: LintSeverity::Warning,
984 location: CircuitLocation {
985 gate_indices: (last_check_index..i).collect(),
986 qubit_indices: vec![],
987 layer: None,
988 subcircuit: None,
989 },
990 message: "Long gate sequence without error mitigation".to_string(),
991 explanation: "Consider adding error mitigation techniques".to_string(),
992 impact: ImpactAnalysis {
993 performance_impact: PerformanceImpact::Low,
994 error_impact: 0.1,
995 resource_impact: ResourceImpact {
996 additional_gates: 5,
997 additional_qubits: 0,
998 depth_increase: 5,
999 memory_overhead: 0.0,
1000 },
1001 hardware_compatibility: vec![],
1002 },
1003 fix_suggestions: vec![FixSuggestion {
1004 description: "Insert dynamical decoupling sequence".to_string(),
1005 automatic: false,
1006 code_changes: vec![],
1007 estimated_improvement: 0.2,
1008 risk_level: RiskLevel::Low,
1009 }],
1010 related_findings: vec![],
1011 confidence: 0.7,
1012 references: vec!["Quantum Error Mitigation Techniques".to_string()],
1013 });
1014 consecutive_gates = 0;
1015 last_check_index = i;
1016 }
1017 }
1018
1019 Ok(findings)
1020 }
1021
1022 fn check_hardware_compatibility(
1024 &self,
1025 circuit: &[QuantumGate],
1026 ) -> Result<Vec<EnhancedLintFinding>, QuantRS2Error> {
1027 let mut findings = Vec::new();
1028
1029 for architecture in &self.config.target_architectures {
1030 let compatibility_issues =
1031 self.check_architecture_compatibility(circuit, architecture)?;
1032 findings.extend(compatibility_issues);
1033 }
1034
1035 Ok(findings)
1036 }
1037
1038 fn check_architecture_compatibility(
1040 &self,
1041 circuit: &[QuantumGate],
1042 architecture: &HardwareArchitecture,
1043 ) -> Result<Vec<EnhancedLintFinding>, QuantRS2Error> {
1044 let mut findings = Vec::new();
1045
1046 let supported_gates = Self::get_supported_gates(architecture);
1048
1049 for (i, gate) in circuit.iter().enumerate() {
1050 if !Self::is_gate_supported(gate.gate_type(), &supported_gates) {
1051 findings.push(EnhancedLintFinding {
1052 finding_type: LintFindingType::UnsupportedGateSet,
1053 severity: LintSeverity::Error,
1054 location: CircuitLocation {
1055 gate_indices: vec![i],
1056 qubit_indices: gate.target_qubits().to_vec(),
1057 layer: None,
1058 subcircuit: None,
1059 },
1060 message: format!(
1061 "Gate {:?} not supported on {:?}",
1062 gate.gate_type(),
1063 architecture
1064 ),
1065 explanation: "This gate requires decomposition for the target hardware"
1066 .to_string(),
1067 impact: ImpactAnalysis {
1068 performance_impact: PerformanceImpact::Medium,
1069 error_impact: 0.05,
1070 resource_impact: ResourceImpact {
1071 additional_gates: 3,
1072 additional_qubits: 0,
1073 depth_increase: 3,
1074 memory_overhead: 0.0,
1075 },
1076 hardware_compatibility: vec![(
1077 *architecture,
1078 Compatibility::RequiresTranspilation,
1079 )],
1080 },
1081 fix_suggestions: vec![FixSuggestion {
1082 description: "Decompose gate into native gate set".to_string(),
1083 automatic: true,
1084 code_changes: vec![],
1085 estimated_improvement: 0.0,
1086 risk_level: RiskLevel::Low,
1087 }],
1088 related_findings: vec![],
1089 confidence: 1.0,
1090 references: vec![format!("{:?} Native Gate Set", architecture)],
1091 });
1092 }
1093 }
1094
1095 Ok(findings)
1096 }
1097
1098 fn apply_custom_rule(
1100 &self,
1101 circuit: &[QuantumGate],
1102 rule: &CustomLintRule,
1103 ) -> Result<Vec<EnhancedLintFinding>, QuantRS2Error> {
1104 let mut findings = Vec::new();
1105
1106 match &rule.pattern {
1108 LintPattern::GateSequence(matchers) => {
1109 for i in 0..=circuit.len().saturating_sub(matchers.len()) {
1110 if Self::matches_pattern(&circuit[i..i + matchers.len()], matchers) {
1111 findings.push(EnhancedLintFinding {
1112 finding_type: LintFindingType::CustomRule(rule.name.clone()),
1113 severity: rule.severity.clone(),
1114 location: CircuitLocation {
1115 gate_indices: (i..i + matchers.len()).collect(),
1116 qubit_indices: vec![],
1117 layer: None,
1118 subcircuit: None,
1119 },
1120 message: rule.name.clone(),
1121 explanation: rule.description.clone(),
1122 impact: ImpactAnalysis {
1123 performance_impact: PerformanceImpact::Medium,
1124 error_impact: 0.0,
1125 resource_impact: ResourceImpact {
1126 additional_gates: 0,
1127 additional_qubits: 0,
1128 depth_increase: 0,
1129 memory_overhead: 0.0,
1130 },
1131 hardware_compatibility: vec![],
1132 },
1133 fix_suggestions: if let Some(fix) = &rule.fix_suggestion {
1134 vec![FixSuggestion {
1135 description: fix.clone(),
1136 automatic: false,
1137 code_changes: vec![],
1138 estimated_improvement: 0.1,
1139 risk_level: RiskLevel::Low,
1140 }]
1141 } else {
1142 vec![]
1143 },
1144 related_findings: vec![],
1145 confidence: 0.9,
1146 references: vec![],
1147 });
1148 }
1149 }
1150 }
1151 _ => {} }
1153
1154 Ok(findings)
1155 }
1156
1157 fn ml_pattern_detection(
1159 &self,
1160 circuit: &[QuantumGate],
1161 ml_detector: &MLPatternDetector,
1162 ) -> Result<Vec<EnhancedLintFinding>, QuantRS2Error> {
1163 let mut findings = Vec::new();
1164
1165 let features = ml_detector
1167 .feature_extractor
1168 .feature_functions
1169 .iter()
1170 .flat_map(|f| f(circuit))
1171 .collect::<Vec<_>>();
1172
1173 let (finding_type, confidence) = (ml_detector.pattern_classifier.classify)(&features);
1175
1176 if confidence >= ml_detector.confidence_threshold {
1177 findings.push(EnhancedLintFinding {
1178 finding_type,
1179 severity: LintSeverity::Info,
1180 location: CircuitLocation {
1181 gate_indices: (0..circuit.len()).collect(),
1182 qubit_indices: vec![],
1183 layer: None,
1184 subcircuit: None,
1185 },
1186 message: "ML-detected pattern".to_string(),
1187 explanation: "Pattern detected by machine learning model".to_string(),
1188 impact: ImpactAnalysis {
1189 performance_impact: PerformanceImpact::Low,
1190 error_impact: 0.0,
1191 resource_impact: ResourceImpact {
1192 additional_gates: 0,
1193 additional_qubits: 0,
1194 depth_increase: 0,
1195 memory_overhead: 0.0,
1196 },
1197 hardware_compatibility: vec![],
1198 },
1199 fix_suggestions: vec![],
1200 related_findings: vec![],
1201 confidence,
1202 references: vec![],
1203 });
1204 }
1205
1206 Ok(findings)
1207 }
1208
1209 fn find_fusion_opportunities(
1211 &self,
1212 circuit: &[QuantumGate],
1213 ) -> Result<Vec<EnhancedLintFinding>, QuantRS2Error> {
1214 let mut findings = Vec::new();
1215
1216 let mut i = 0;
1218 while i < circuit.len() {
1219 if Self::is_single_qubit_gate(&circuit[i]) {
1220 let target_qubit = circuit[i].target_qubits()[0];
1221 let mut j = i + 1;
1222
1223 while j < circuit.len()
1224 && Self::is_single_qubit_gate(&circuit[j])
1225 && circuit[j].target_qubits()[0] == target_qubit
1226 {
1227 j += 1;
1228 }
1229
1230 if j - i > 2 {
1231 findings.push(EnhancedLintFinding {
1232 finding_type: LintFindingType::MissedFusionOpportunity,
1233 severity: LintSeverity::Info,
1234 location: CircuitLocation {
1235 gate_indices: (i..j).collect(),
1236 qubit_indices: vec![target_qubit],
1237 layer: None,
1238 subcircuit: None,
1239 },
1240 message: format!("{} consecutive single-qubit gates can be fused", j - i),
1241 explanation: "Multiple single-qubit gates can be combined into one"
1242 .to_string(),
1243 impact: ImpactAnalysis {
1244 performance_impact: PerformanceImpact::Low,
1245 error_impact: -0.01,
1246 resource_impact: ResourceImpact {
1247 additional_gates: -(j as i32 - i as i32 - 1),
1248 additional_qubits: 0,
1249 depth_increase: -(j as i32 - i as i32 - 1),
1250 memory_overhead: 0.0,
1251 },
1252 hardware_compatibility: vec![],
1253 },
1254 fix_suggestions: vec![FixSuggestion {
1255 description: "Fuse gates into single unitary".to_string(),
1256 automatic: true,
1257 code_changes: vec![],
1258 estimated_improvement: 0.15,
1259 risk_level: RiskLevel::Safe,
1260 }],
1261 related_findings: vec![],
1262 confidence: 0.95,
1263 references: vec!["Gate Fusion Optimization".to_string()],
1264 });
1265 }
1266
1267 i = j;
1268 } else {
1269 i += 1;
1270 }
1271 }
1272
1273 Ok(findings)
1274 }
1275
1276 fn are_inverse_gates(gate1: &QuantumGate, gate2: &QuantumGate) -> bool {
1278 use GateType::{H, S, T, X, Y, Z};
1279
1280 if gate1.target_qubits() != gate2.target_qubits() {
1281 return false;
1282 }
1283
1284 matches!(
1285 (gate1.gate_type(), gate2.gate_type()),
1286 (X, X) | (Y, Y) | (Z, Z) | (H, H) | (S, S) | (T, T)
1287 )
1288 }
1289
1290 fn calculate_circuit_depth(circuit: &[QuantumGate]) -> usize {
1291 if circuit.is_empty() {
1292 return 0;
1293 }
1294
1295 let max_qubit = circuit
1296 .iter()
1297 .flat_map(|g| g.target_qubits())
1298 .max()
1299 .copied()
1300 .unwrap_or(0);
1301
1302 let mut qubit_depths = vec![0; max_qubit + 1];
1303
1304 for gate in circuit {
1305 let max_depth = gate
1306 .target_qubits()
1307 .iter()
1308 .map(|&q| qubit_depths[q])
1309 .max()
1310 .unwrap_or(0);
1311
1312 for &qubit in gate.target_qubits() {
1313 qubit_depths[qubit] = max_depth + 1;
1314 }
1315
1316 if let Some(control_qubits) = gate.control_qubits() {
1317 for &qubit in control_qubits {
1318 qubit_depths[qubit] = max_depth + 1;
1319 }
1320 }
1321 }
1322
1323 *qubit_depths.iter().max().unwrap_or(&0)
1324 }
1325
1326 fn count_qubits(circuit: &[QuantumGate]) -> usize {
1327 circuit
1328 .iter()
1329 .flat_map(|g| {
1330 let mut qubits = g.target_qubits().to_vec();
1331 if let Some(controls) = g.control_qubits() {
1332 qubits.extend(controls);
1333 }
1334 qubits
1335 })
1336 .collect::<HashSet<_>>()
1337 .len()
1338 }
1339
1340 fn matches_pattern(gates: &[QuantumGate], pattern: &[GatePatternMatcher]) -> bool {
1341 if gates.len() != pattern.len() {
1342 return false;
1343 }
1344
1345 gates.iter().zip(pattern.iter()).all(|(gate, matcher)| {
1346 if let Some(expected_type) = &matcher.gate_type {
1347 if gate.gate_type() != expected_type {
1348 return false;
1349 }
1350 }
1351
1352 if let Some(expected_count) = matcher.qubit_count {
1353 if gate.target_qubits().len() != expected_count {
1354 return false;
1355 }
1356 }
1357
1358 if let Some(expected_controlled) = matcher.is_controlled {
1359 if gate.control_qubits().is_some() != expected_controlled {
1360 return false;
1361 }
1362 }
1363
1364 true
1365 })
1366 }
1367
1368 fn find_algorithm_signature(
1369 circuit: &[QuantumGate],
1370 signature: &AlgorithmSignature,
1371 ) -> Option<Vec<usize>> {
1372 let sig_len = signature.gate_sequence.len();
1373
1374 if sig_len > circuit.len() {
1375 return None;
1376 }
1377
1378 for i in 0..=circuit.len() - sig_len {
1379 let matches = circuit[i..i + sig_len]
1380 .iter()
1381 .zip(&signature.gate_sequence)
1382 .all(|(gate, expected)| gate.gate_type() == expected);
1383
1384 if matches {
1385 return Some((i..i + sig_len).collect());
1386 }
1387 }
1388
1389 None
1390 }
1391
1392 fn is_single_qubit_gate(gate: &QuantumGate) -> bool {
1393 gate.target_qubits().len() == 1 && gate.control_qubits().is_none()
1394 }
1395
1396 fn get_supported_gates(architecture: &HardwareArchitecture) -> HashSet<GateType> {
1397 use GateType::{Rx, Ry, Rz, CNOT, CZ, H, S, T, X, Y, Z};
1398
1399 match architecture {
1400 HardwareArchitecture::IBMQ => vec![
1401 X,
1402 Y,
1403 Z,
1404 H,
1405 S,
1406 T,
1407 Rx("0.0".to_string()),
1408 Ry("0.0".to_string()),
1409 Rz("0.0".to_string()),
1410 CNOT,
1411 CZ,
1412 ]
1413 .into_iter()
1414 .collect(),
1415 HardwareArchitecture::IonQ => vec![
1416 X,
1417 Y,
1418 Z,
1419 H,
1420 Rx("0.0".to_string()),
1421 Ry("0.0".to_string()),
1422 Rz("0.0".to_string()),
1423 CNOT,
1424 ]
1425 .into_iter()
1426 .collect(),
1427 _ => {
1428 vec![
1430 X,
1431 Y,
1432 Z,
1433 H,
1434 S,
1435 T,
1436 Rx("0.0".to_string()),
1437 Ry("0.0".to_string()),
1438 Rz("0.0".to_string()),
1439 CNOT,
1440 CZ,
1441 ]
1442 .into_iter()
1443 .collect()
1444 }
1445 }
1446 }
1447
1448 fn is_gate_supported(gate_type: &GateType, supported: &HashSet<GateType>) -> bool {
1449 use GateType::{Rx, Ry, Rz};
1450
1451 match gate_type {
1452 Rx(_) => supported.contains(&Rx("0.0".to_string())),
1453 Ry(_) => supported.contains(&Ry("0.0".to_string())),
1454 Rz(_) => supported.contains(&Rz("0.0".to_string())),
1455 other => supported.contains(other),
1456 }
1457 }
1458
1459 fn create_pattern_finding(
1460 &self,
1461 pattern_id: &str,
1462 location: usize,
1463 gates: &[QuantumGate],
1464 ) -> Result<EnhancedLintFinding, QuantRS2Error> {
1465 let finding_type = match pattern_id {
1466 "double_hadamard" => LintFindingType::RedundantGates,
1467 _ => LintFindingType::CustomRule(pattern_id.to_string()),
1468 };
1469
1470 Ok(EnhancedLintFinding {
1471 finding_type,
1472 severity: LintSeverity::Warning,
1473 location: CircuitLocation {
1474 gate_indices: (location..location + 2).collect(),
1475 qubit_indices: gates[0].target_qubits().to_vec(),
1476 layer: None,
1477 subcircuit: None,
1478 },
1479 message: format!("Pattern '{pattern_id}' detected"),
1480 explanation: "This pattern can be optimized".to_string(),
1481 impact: ImpactAnalysis {
1482 performance_impact: PerformanceImpact::Low,
1483 error_impact: 0.0,
1484 resource_impact: ResourceImpact {
1485 additional_gates: -1,
1486 additional_qubits: 0,
1487 depth_increase: -1,
1488 memory_overhead: 0.0,
1489 },
1490 hardware_compatibility: vec![],
1491 },
1492 fix_suggestions: vec![],
1493 related_findings: vec![],
1494 confidence: 0.9,
1495 references: vec![],
1496 })
1497 }
1498
1499 fn compute_cache_key(&self, circuit: &[QuantumGate]) -> String {
1500 format!("{circuit:?}")
1501 }
1502
1503 fn check_cache(&self, key: &str) -> Option<Vec<EnhancedLintFinding>> {
1504 self.cache
1505 .lock()
1506 .ok()
1507 .and_then(|guard| guard.findings.get(key).cloned())
1508 }
1509
1510 fn update_cache(&self, key: String, findings: Vec<EnhancedLintFinding>) {
1511 if let Ok(mut guard) = self.cache.lock() {
1512 guard.findings.insert(key, findings);
1513 }
1514 }
1515
1516 fn update_statistics(&self, findings: &[EnhancedLintFinding]) {
1517 let Ok(mut stats) = self.statistics.lock() else {
1518 return;
1519 };
1520
1521 stats.total_findings += findings.len();
1522
1523 for finding in findings {
1524 *stats
1525 .findings_by_type
1526 .entry(finding.finding_type.clone())
1527 .or_insert(0) += 1;
1528 *stats
1529 .findings_by_severity
1530 .entry(finding.severity.clone())
1531 .or_insert(0) += 1;
1532 }
1533 }
1534
1535 fn create_report(
1536 &self,
1537 findings: Vec<EnhancedLintFinding>,
1538 analysis_time: std::time::Duration,
1539 ) -> EnhancedLintingReport {
1540 let stats = self
1541 .statistics
1542 .lock()
1543 .map(|g| g.clone())
1544 .unwrap_or_default();
1545
1546 let summary = LintingSummary {
1547 total_findings: findings.len(),
1548 findings_by_severity: Self::count_by_severity(&findings),
1549 findings_by_type: Self::count_by_type(&findings),
1550 analysis_time,
1551 circuits_analyzed: stats.total_circuits_analyzed,
1552 };
1553
1554 let metrics = QualityMetrics {
1555 circuit_quality_score: Self::calculate_quality_score(&findings),
1556 performance_score: Self::calculate_performance_score(&findings),
1557 hardware_readiness_score: Self::calculate_hardware_score(&findings),
1558 maintainability_score: Self::calculate_maintainability_score(&findings),
1559 };
1560
1561 EnhancedLintingReport {
1562 summary,
1563 findings: findings.clone(),
1564 metrics,
1565 recommendations: self.generate_recommendations(&findings),
1566 statistics: stats.clone(),
1567 }
1568 }
1569
1570 fn count_by_severity(findings: &[EnhancedLintFinding]) -> HashMap<LintSeverity, usize> {
1571 let mut counts = HashMap::new();
1572 for finding in findings {
1573 *counts.entry(finding.severity.clone()).or_insert(0) += 1;
1574 }
1575 counts
1576 }
1577
1578 fn count_by_type(findings: &[EnhancedLintFinding]) -> HashMap<LintFindingType, usize> {
1579 let mut counts = HashMap::new();
1580 for finding in findings {
1581 *counts.entry(finding.finding_type.clone()).or_insert(0) += 1;
1582 }
1583 counts
1584 }
1585
1586 fn calculate_quality_score(findings: &[EnhancedLintFinding]) -> f64 {
1587 let base_score = 100.0;
1588 let deductions: f64 = findings
1589 .iter()
1590 .map(|f| match f.severity {
1591 LintSeverity::Critical => 10.0,
1592 LintSeverity::Error => 5.0,
1593 LintSeverity::Warning => 2.0,
1594 LintSeverity::Info => 0.5,
1595 })
1596 .sum();
1597
1598 (base_score - deductions).max(0.0)
1599 }
1600
1601 fn calculate_performance_score(findings: &[EnhancedLintFinding]) -> f64 {
1602 let performance_findings = findings
1603 .iter()
1604 .filter(|f| {
1605 matches!(
1606 f.finding_type,
1607 LintFindingType::RedundantGates
1608 | LintFindingType::InefficientDecomposition
1609 | LintFindingType::MissedFusionOpportunity
1610 | LintFindingType::SuboptimalGateOrder
1611 )
1612 })
1613 .count();
1614
1615 (performance_findings as f64).mul_add(-5.0, 100.0)
1616 }
1617
1618 fn calculate_hardware_score(findings: &[EnhancedLintFinding]) -> f64 {
1619 let hardware_findings = findings
1620 .iter()
1621 .filter(|f| {
1622 matches!(
1623 f.finding_type,
1624 LintFindingType::UnsupportedGateSet
1625 | LintFindingType::ConnectivityViolation
1626 | LintFindingType::ExceedsCoherenceTime
1627 )
1628 })
1629 .count();
1630
1631 (hardware_findings as f64).mul_add(-10.0, 100.0)
1632 }
1633
1634 fn calculate_maintainability_score(findings: &[EnhancedLintFinding]) -> f64 {
1635 let maintainability_findings = findings
1636 .iter()
1637 .filter(|f| {
1638 matches!(
1639 f.finding_type,
1640 LintFindingType::LackOfModularity | LintFindingType::InadequateParameterization
1641 )
1642 })
1643 .count();
1644
1645 (maintainability_findings as f64).mul_add(-8.0, 100.0)
1646 }
1647
1648 fn generate_recommendations(&self, findings: &[EnhancedLintFinding]) -> Vec<String> {
1649 let mut recommendations = Vec::new();
1650
1651 let critical_count = findings
1652 .iter()
1653 .filter(|f| f.severity == LintSeverity::Critical)
1654 .count();
1655
1656 if critical_count > 0 {
1657 recommendations.push(format!(
1658 "Address {critical_count} critical issues before deployment"
1659 ));
1660 }
1661
1662 let performance_issues = findings
1663 .iter()
1664 .filter(|f| {
1665 matches!(
1666 f.impact.performance_impact,
1667 PerformanceImpact::High | PerformanceImpact::Critical
1668 )
1669 })
1670 .count();
1671
1672 if performance_issues > 0 {
1673 recommendations
1674 .push("Consider circuit optimization to improve performance".to_string());
1675 }
1676
1677 recommendations
1678 }
1679}
1680
1681#[derive(Debug, Clone, Serialize, Deserialize)]
1683pub struct CircuitMetadata {
1684 pub name: String,
1685 pub version: String,
1686 pub target_hardware: Option<HardwareArchitecture>,
1687 pub algorithm_type: Option<String>,
1688 pub expected_depth: Option<usize>,
1689 pub expected_gate_count: Option<usize>,
1690}
1691
1692#[derive(Debug, Clone, Serialize, Deserialize)]
1694pub struct EnhancedLintingReport {
1695 pub summary: LintingSummary,
1696 pub findings: Vec<EnhancedLintFinding>,
1697 pub metrics: QualityMetrics,
1698 pub recommendations: Vec<String>,
1699 pub statistics: LintStatistics,
1700}
1701
1702#[derive(Debug, Clone, Serialize, Deserialize)]
1703pub struct LintingSummary {
1704 pub total_findings: usize,
1705 pub findings_by_severity: HashMap<LintSeverity, usize>,
1706 pub findings_by_type: HashMap<LintFindingType, usize>,
1707 pub analysis_time: std::time::Duration,
1708 pub circuits_analyzed: usize,
1709}
1710
1711#[derive(Debug, Clone, Serialize, Deserialize)]
1712pub struct QualityMetrics {
1713 pub circuit_quality_score: f64,
1714 pub performance_score: f64,
1715 pub hardware_readiness_score: f64,
1716 pub maintainability_score: f64,
1717}
1718
1719#[cfg(test)]
1720mod tests {
1721 use super::*;
1722
1723 #[test]
1724 fn test_enhanced_linter_creation() {
1725 let linter = EnhancedQuantumLinter::new();
1726 assert!(linter.config.enable_ml_pattern_detection);
1727 }
1728
1729 #[test]
1730 fn test_redundant_gates_detection() {
1731 let linter = EnhancedQuantumLinter::new();
1732 let gates = vec![
1733 QuantumGate::new(GateType::X, vec![0], None),
1734 QuantumGate::new(GateType::X, vec![0], None), ];
1736
1737 let report = linter
1738 .lint_circuit(&gates, None)
1739 .expect("Failed to lint circuit");
1740 assert!(report
1741 .findings
1742 .iter()
1743 .any(|f| f.finding_type == LintFindingType::RedundantGates));
1744 }
1745
1746 #[test]
1747 fn test_pattern_matching() {
1748 let linter = EnhancedQuantumLinter::new();
1749 let gates = vec![
1750 QuantumGate::new(GateType::H, vec![0], None),
1751 QuantumGate::new(GateType::H, vec![0], None), ];
1753
1754 let report = linter
1755 .lint_circuit(&gates, None)
1756 .expect("Failed to lint circuit");
1757 assert!(!report.findings.is_empty());
1758 }
1759
1760 #[test]
1761 fn test_complexity_analysis() {
1762 let config = EnhancedLintingConfig {
1763 enable_complexity_analysis: true,
1764 ..Default::default()
1765 };
1766 let linter = EnhancedQuantumLinter::with_config(config);
1767
1768 let mut gates = Vec::new();
1769 for i in 0..60 {
1770 gates.push(QuantumGate::new(GateType::T, vec![i % 5], None));
1771 }
1772
1773 let report = linter
1774 .lint_circuit(&gates, None)
1775 .expect("Failed to lint circuit");
1776 assert!(report.findings.iter().any(|f|
1777 matches!(f.finding_type, LintFindingType::CustomRule(ref s) if s.contains("T-count"))
1778 ));
1779 }
1780
1781 #[test]
1782 fn test_hardware_compatibility() {
1783 let config = EnhancedLintingConfig {
1784 enable_hardware_specific_linting: true,
1785 target_architectures: vec![HardwareArchitecture::IBMQ],
1786 ..Default::default()
1787 };
1788 let linter = EnhancedQuantumLinter::with_config(config);
1789
1790 let gates = vec![
1791 QuantumGate::new(
1793 GateType::Controlled(Box::new(GateType::Controlled(Box::new(GateType::X)))),
1794 vec![2], Some(vec![0, 1]), ),
1797 ];
1798
1799 let report = linter
1800 .lint_circuit(&gates, None)
1801 .expect("Failed to lint circuit");
1802 assert!(report
1803 .findings
1804 .iter()
1805 .any(|f| f.finding_type == LintFindingType::UnsupportedGateSet));
1806 }
1807
1808 #[test]
1809 fn test_custom_rules() {
1810 let custom_rule = CustomLintRule {
1811 name: "No X after Z".to_string(),
1812 description: "X gate should not follow Z gate".to_string(),
1813 pattern: LintPattern::GateSequence(vec![
1814 GatePatternMatcher {
1815 gate_type: Some(GateType::Z),
1816 qubit_count: None,
1817 is_controlled: None,
1818 is_parameterized: None,
1819 },
1820 GatePatternMatcher {
1821 gate_type: Some(GateType::X),
1822 qubit_count: None,
1823 is_controlled: None,
1824 is_parameterized: None,
1825 },
1826 ]),
1827 severity: LintSeverity::Warning,
1828 fix_suggestion: Some("Reorder gates".to_string()),
1829 };
1830
1831 let config = EnhancedLintingConfig {
1832 custom_rules: vec![custom_rule],
1833 ..Default::default()
1834 };
1835 let linter = EnhancedQuantumLinter::with_config(config);
1836
1837 let gates = vec![
1838 QuantumGate::new(GateType::Z, vec![0], None),
1839 QuantumGate::new(GateType::X, vec![0], None),
1840 ];
1841
1842 let report = linter
1843 .lint_circuit(&gates, None)
1844 .expect("Failed to lint circuit");
1845 assert!(report.findings.iter().any(|f|
1846 matches!(f.finding_type, LintFindingType::CustomRule(ref s) if s.contains("No X after Z"))
1847 ));
1848 }
1849
1850 #[test]
1851 fn test_quality_metrics() {
1852 let linter = EnhancedQuantumLinter::new();
1853 let gates = vec![
1854 QuantumGate::new(GateType::H, vec![0], None),
1855 QuantumGate::new(GateType::CNOT, vec![0, 1], None),
1856 ];
1857
1858 let report = linter
1859 .lint_circuit(&gates, None)
1860 .expect("Failed to lint circuit");
1861 assert!(report.metrics.circuit_quality_score > 0.0);
1862 assert!(report.metrics.performance_score > 0.0);
1863 assert!(report.metrics.hardware_readiness_score > 0.0);
1864 assert!(report.metrics.maintainability_score > 0.0);
1865 }
1866}