pyroboreplay 2.7.0__tar.gz → 2.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/Cargo.lock +1 -1
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/Cargo.toml +1 -1
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/PKG-INFO +2 -2
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/pyproject.toml +2 -2
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/lib.rs +1 -0
- pyroboreplay-2.8.0/src/phase20/counterfactual_scenarios.rs +299 -0
- pyroboreplay-2.8.0/src/phase20/decision_tree.rs +452 -0
- pyroboreplay-2.8.0/src/phase20/mod.rs +12 -0
- pyroboreplay-2.8.0/src/phase20/rule_extraction.rs +286 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/.env.example +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/.gitattributes +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/.github/CI_SETUP.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/.github/workflows/ci.yml +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/.github/workflows/docs.yml +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/.github/workflows/release.yml +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/.github/workflows/security.yml +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/.gitignore +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/CAUSALITY_DECISION_ENGINE_VISION.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/CLI_STATS_DASHBOARD_FEATURE.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/CONTRIBUTING.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/FINAL_REPORT.txt +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/IMPLEMENTATION_SUMMARY.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/LICENSE +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/OTEL_SETUP_GUIDE.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/PHASE16_CAUSAL_GRAPHS_ROADMAP.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/PRODUCTION_DEPLOYMENT.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/README.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/ROADMAP.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/SECURITY.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/STATS_DASHBOARD.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/STATS_DASHBOARD_QUICKSTART.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/API.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/ARCHITECTURE.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/ARCHITECTURE_COMPLETE.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/BUILD_SUMMARY.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/CAMERA_EXPORT.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/CLAUDE.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/CODE_OF_CONDUCT.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/GITHUB_SETTINGS.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/IMPLEMENTATION_STATUS.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/IMU_VISUALIZATION.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/KEYBOARD_SHORTCUTS.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/LIDAR_VISUALIZATION.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/MLRIAS_ARCHITECTURE.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/MLRIAS_PHASES_COMPLETE.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/PHASE1_COMPLETION_REPORT.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/PHASE1_IMPLEMENTATION.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/PHASE2_ADAPTER_STRATEGY.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/PHASE2_TESTING_COMPLETE.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/PHASE3_COMPLETE.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/PHASE3_PHASE4_ROADMAP.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/PHASE4_COMPLETE.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/PRODUCT_STRATEGY.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/PUBLISH.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/QUICKSTART.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/RELEASES.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/RELEASE_v2.0.0.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/REVISED_ROADMAP_PHASES_5_ONWARDS.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/ROADMAP.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/SENSOR_METADATA.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/TESTING_COMPLETE.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/TESTING_PLAN.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/docs/TESTING_STATUS.md +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/camera_export_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/causal_analysis_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/causal_query_engine_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/causal_visualization_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/compliance_report_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/correlation_analysis_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/counterfactual_reasoning_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/coverage_evolution_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/deterministic_replay_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/diagnostic_report_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/failover_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/fleet_monitor_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/generate_warehouse_mission.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/imu_visualization_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/keyboard_shortcuts_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/lidar_visualization_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/multi_robot_coordination_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/phase1_complete_diagnostics.py +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/pyterrain_bridge_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/recommendation_engine_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/root_cause_analysis_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/sensor_metadata_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/spatial_causality_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/sqlite_backend_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/stats_dashboard_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/storage_backend_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/streaming_demo.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/examples/test_python_api.py +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/otel_exporter.py +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/pyroboreplay/_mcp_connector.py +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/pyroboreplay/_mcp_tools.py +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/pyroboreplay/scripts/__init__.py.bak +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/pyroboreplay.toml +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/scripts/test_dashboards_crossplatform.sh +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/adapters/configuration.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/adapters/linux_log.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/adapters/metrics.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/adapters/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/adapters/ros2.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/adaptive_recalibration.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/aggregation.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/coordination/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/drift_detection.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/environmental/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/evidence_quality_scoring.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/feedback_loop.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/fleet_learning.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/gap_narrative_pipeline.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/gap_to_causal.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/historical.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/incident_narrative.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/multi_factor_causality.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/phase3_validation.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/phase4_integration.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/physical/mechanical_degradation.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/physical/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/physical/structural_dynamics.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/physical/thermal_effects.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/predictive_gaps.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/quality_confidence.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/recalibration.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/robot_calibration.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/scoring.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/sensor/detection_robustness.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/sensor/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/sensor/optical_contamination.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/severity.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/severity_contracts.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/system/clock_drift.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/system/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/telemetry.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/test_data.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/analyzers/validation.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/args.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/camera_export.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/causal_viz.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/consolidated_output.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/gap_analysis.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/imu_viz.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/json_output.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/keyboard.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/lidar_viz.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/replay_ui.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/sensor_stats.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/stats_dashboard.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/cli/tests_consolidation_integration.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/anomaly_detector.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/causality.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/compliance.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/confidence_scoring.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/correlation.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/counterfactual.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/coverage_evolution.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/cross_mission.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/deterministic_replay.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/diagnostic_report.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/event.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/evidence_discovery.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/explanation.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/failure_actions.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/failure_detection/localization.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/failure_detection/middleware.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/failure_detection/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/failure_detection/navigation.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/failure_detection/perception.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/failure_detection/system.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/geospatial_export.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/incident_analysis.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/incident_bundle.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/multi_robot.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/pyterrain_bridge.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/recommendation.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/recommendations_engine.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/root_cause.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/spatial_causality.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/timeline.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/core/timeline_correlation.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/fusion/forensic_reporter.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/fusion/invisible_person_detector.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/fusion/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/fusion/rgb_thermal_fusion.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/fusion/thermal_model.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/intelligence/agent_friendly_output.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/intelligence/event_extraction.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/intelligence/hidden_explanations.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/intelligence/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/intelligence/perception_gap_analysis.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/intelligence/scene_reconstruction.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/knowledge/change_detection.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/knowledge/fleet_terrain_learning.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/knowledge/knowledge_graph.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/knowledge/longitudinal_reasoning.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/knowledge/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/knowledge/multi_mission_learning.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/knowledge/spatial_grounding.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/knowledge/temporal_analysis.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/knowledge/terrain_integration.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/knowledge/world_model.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/main.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/perception/detection_backends.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/perception/detection_orchestrator.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/perception/gap_context_analyzer.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/perception/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/perception/object_detection.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/perception/object_tracking.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/perception/perception_analysis.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/perception/retrospective_detection.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/perception/scene_understanding.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase14/analyzer_capabilities.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase14/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase14/modality_adapters.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase14/navigation_session.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase14/temporal_sync.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase14/timeline_indexing.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase14/video_processing.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase15/costmap_analyzer.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase15/dynamic_obstacle_analyzer.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase15/failure_detector.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase15/finding_generator.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase15/localization_analyzer.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase15/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase15/nav2_limitation_detector.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase15/planner_analyzer.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase15/root_cause_generator.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase15/semantic_gap_analyzer.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase16/causal_builder.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase16/decision_reconstructor.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase16/graph_validator.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase16/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase16/pattern_matcher.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase17/alternative_timeline.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase17/counterfactual.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase17/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase17/outcome_influence.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase18/decision_clustering.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase18/fleet_learning.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase18/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase18/pattern_discovery.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase19/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase19/temporal_patterns.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase19/trend_detector.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/phase19/window_analyzer.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/pyroboreplay/__init__.py +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/reasoning/explanation_generator.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/reasoning/incident_patterns.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/reasoning/llm_integration.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/reasoning/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/reasoning/semantic_search.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/storage/audit.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/storage/backend.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/storage/backends.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/storage/failover.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/storage/inmemory.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/storage/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/storage/sqlite.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/streaming/channel.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/streaming/fleet_monitor.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/streaming/kafka_stub.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/streaming/live_diagnostics.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/streaming/mod.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/streaming/processor.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/src/streaming/sla.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/tests/integration_tests.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/tests/test_actions.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/tests/test_anomaly_detector.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/tests/test_edge_cases.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/tests/test_explanation.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/tests/test_geospatial_export.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/tests/test_mlrias_integration.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/tests/test_performance.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/tests/test_phase2_patterns.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/tests/test_phase2_prediction.rs +0 -0
- {pyroboreplay-2.7.0 → pyroboreplay-2.8.0}/tests/test_python_api_integration.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyroboreplay
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.8.0
|
|
4
4
|
Classifier: Development Status :: 5 - Production/Stable
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -22,7 +22,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
22
22
|
Classifier: Topic :: System :: Monitoring
|
|
23
23
|
Classifier: Topic :: System :: Networking
|
|
24
24
|
License-File: LICENSE
|
|
25
|
-
Summary: AI Navigation Reliability Engineer for autonomous robots. Phase
|
|
25
|
+
Summary: AI Navigation Reliability Engineer for autonomous robots. Phase 20: Causal decision trees & counterfactual analysis (25 tests). Rule extraction, scenario simulation, tree-based interpretability.
|
|
26
26
|
Keywords: robotics,debugging,mission-replay,root-cause-analysis,ros2,observability,fault-diagnosis,autonomous-systems,fleet-monitoring,sla-enforcement,time-travel-debugging
|
|
27
27
|
Author-email: Georgi Mammen Mullassery <mullassery@gmail.com>
|
|
28
28
|
License: Proprietary
|
|
@@ -4,8 +4,8 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyroboreplay"
|
|
7
|
-
version = "2.
|
|
8
|
-
description = "AI Navigation Reliability Engineer for autonomous robots. Phase
|
|
7
|
+
version = "2.8.0"
|
|
8
|
+
description = "AI Navigation Reliability Engineer for autonomous robots. Phase 20: Causal decision trees & counterfactual analysis (25 tests). Rule extraction, scenario simulation, tree-based interpretability."
|
|
9
9
|
authors = [{name = "Georgi Mammen Mullassery", email = "mullassery@gmail.com"}]
|
|
10
10
|
license = {text = "Proprietary"}
|
|
11
11
|
readme = "README.md"
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/// Counterfactual Scenario Analysis - What-if analysis with impact prediction
|
|
2
|
+
|
|
3
|
+
use serde::{Deserialize, Serialize};
|
|
4
|
+
use std::collections::HashMap;
|
|
5
|
+
|
|
6
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
7
|
+
pub struct CounterfactualScenario {
|
|
8
|
+
pub scenario_id: String,
|
|
9
|
+
pub name: String,
|
|
10
|
+
pub description: String,
|
|
11
|
+
pub modifications: HashMap<String, f32>, // Feature -> hypothetical value
|
|
12
|
+
pub predicted_outcome: String,
|
|
13
|
+
pub confidence: f32,
|
|
14
|
+
pub impact_magnitude: f32, // How much different from baseline?
|
|
15
|
+
pub affected_features: Vec<String>,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
impl CounterfactualScenario {
|
|
19
|
+
pub fn new(name: String) -> Self {
|
|
20
|
+
CounterfactualScenario {
|
|
21
|
+
scenario_id: format!("scenario_{}", uuid::Uuid::new_v4()),
|
|
22
|
+
name,
|
|
23
|
+
description: String::new(),
|
|
24
|
+
modifications: HashMap::new(),
|
|
25
|
+
predicted_outcome: String::new(),
|
|
26
|
+
confidence: 0.0,
|
|
27
|
+
impact_magnitude: 0.0,
|
|
28
|
+
affected_features: Vec::new(),
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
pub fn impact_score(&self) -> f32 {
|
|
33
|
+
// Impact based on magnitude and confidence
|
|
34
|
+
self.impact_magnitude * self.confidence
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
pub struct ScenarioAnalyzer {
|
|
39
|
+
baseline_features: HashMap<String, f32>,
|
|
40
|
+
scenario_history: Vec<CounterfactualScenario>,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
impl ScenarioAnalyzer {
|
|
44
|
+
pub fn new(baseline: HashMap<String, f32>) -> Self {
|
|
45
|
+
ScenarioAnalyzer {
|
|
46
|
+
baseline_features: baseline,
|
|
47
|
+
scenario_history: Vec::new(),
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// Create a counterfactual scenario by modifying baseline features
|
|
52
|
+
pub fn create_scenario(
|
|
53
|
+
&mut self,
|
|
54
|
+
scenario_name: String,
|
|
55
|
+
modifications: HashMap<String, f32>,
|
|
56
|
+
) -> CounterfactualScenario {
|
|
57
|
+
let mut scenario = CounterfactualScenario::new(scenario_name);
|
|
58
|
+
|
|
59
|
+
scenario.modifications = modifications.clone();
|
|
60
|
+
scenario.affected_features = modifications.keys().cloned().collect();
|
|
61
|
+
|
|
62
|
+
// Calculate impact magnitude
|
|
63
|
+
let mut total_change = 0.0;
|
|
64
|
+
for (feature, hypothetical_value) in &modifications {
|
|
65
|
+
let baseline_value = self.baseline_features.get(feature).unwrap_or(&0.0);
|
|
66
|
+
let change = (hypothetical_value - baseline_value).abs();
|
|
67
|
+
total_change += change;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
scenario.impact_magnitude = total_change / scenario.affected_features.len().max(1) as f32;
|
|
71
|
+
|
|
72
|
+
self.scenario_history.push(scenario.clone());
|
|
73
|
+
scenario
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// Analyze how features cascade through a causal network
|
|
77
|
+
pub fn analyze_cascade(
|
|
78
|
+
&self,
|
|
79
|
+
scenario: &CounterfactualScenario,
|
|
80
|
+
causal_map: &HashMap<String, Vec<String>>,
|
|
81
|
+
) -> HashMap<String, f32> {
|
|
82
|
+
let mut cascading_effects: HashMap<String, f32> = HashMap::new();
|
|
83
|
+
|
|
84
|
+
// Start with direct modifications
|
|
85
|
+
for (feature, value) in &scenario.modifications {
|
|
86
|
+
cascading_effects.insert(feature.clone(), *value);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Propagate effects through causal chain
|
|
90
|
+
let mut iterations = 0;
|
|
91
|
+
let max_iterations = 10;
|
|
92
|
+
|
|
93
|
+
while iterations < max_iterations {
|
|
94
|
+
let mut new_effects = cascading_effects.clone();
|
|
95
|
+
let mut changed = false;
|
|
96
|
+
|
|
97
|
+
for (source, targets) in causal_map {
|
|
98
|
+
if let Some(&source_value) = cascading_effects.get(source) {
|
|
99
|
+
for target in targets {
|
|
100
|
+
// Simple propagation: effect attenuates by 0.7x per hop
|
|
101
|
+
let indirect_effect = source_value * 0.7;
|
|
102
|
+
|
|
103
|
+
if !new_effects.contains_key(target)
|
|
104
|
+
|| (new_effects.get(target).unwrap_or(&0.0) - indirect_effect).abs() > 0.01
|
|
105
|
+
{
|
|
106
|
+
new_effects.insert(target.clone(), indirect_effect);
|
|
107
|
+
changed = true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
cascading_effects = new_effects;
|
|
114
|
+
|
|
115
|
+
if !changed {
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
iterations += 1;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
cascading_effects
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/// Generate multiple scenarios to test robustness
|
|
126
|
+
pub fn generate_sensitivity_analysis(
|
|
127
|
+
&mut self,
|
|
128
|
+
feature: String,
|
|
129
|
+
range: (f32, f32),
|
|
130
|
+
steps: usize,
|
|
131
|
+
) -> Vec<CounterfactualScenario> {
|
|
132
|
+
let mut scenarios = Vec::new();
|
|
133
|
+
let baseline = self.baseline_features.get(&feature).unwrap_or(&0.0);
|
|
134
|
+
|
|
135
|
+
let step_size = (range.1 - range.0) / (steps as f32 - 1.0);
|
|
136
|
+
|
|
137
|
+
for i in 0..steps {
|
|
138
|
+
let value = range.0 + (i as f32 * step_size);
|
|
139
|
+
let mut modifications = HashMap::new();
|
|
140
|
+
modifications.insert(feature.clone(), value);
|
|
141
|
+
|
|
142
|
+
let scenario_name = format!("{}_sensitivity_{}", feature, i);
|
|
143
|
+
let scenario = self.create_scenario(scenario_name, modifications);
|
|
144
|
+
|
|
145
|
+
scenarios.push(scenario);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
scenarios
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/// Compare two scenarios to understand trade-offs
|
|
152
|
+
pub fn compare_scenarios(
|
|
153
|
+
&self,
|
|
154
|
+
scenario_a: &CounterfactualScenario,
|
|
155
|
+
scenario_b: &CounterfactualScenario,
|
|
156
|
+
) -> HashMap<String, f32> {
|
|
157
|
+
let mut comparison = HashMap::new();
|
|
158
|
+
|
|
159
|
+
// Find common modifications
|
|
160
|
+
for feature in &scenario_a.affected_features {
|
|
161
|
+
let mod_a = scenario_a.modifications.get(feature).unwrap_or(&0.0);
|
|
162
|
+
let mod_b = scenario_b.modifications.get(feature).unwrap_or(&0.0);
|
|
163
|
+
|
|
164
|
+
let diff = (mod_b - mod_a).abs();
|
|
165
|
+
comparison.insert(format!("diff_{}", feature), diff);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
comparison.insert("impact_diff".to_string(),
|
|
169
|
+
(scenario_b.impact_magnitude - scenario_a.impact_magnitude).abs());
|
|
170
|
+
|
|
171
|
+
comparison
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/// Get scenario statistics
|
|
175
|
+
pub fn get_statistics(&self) -> HashMap<String, f32> {
|
|
176
|
+
let mut stats = HashMap::new();
|
|
177
|
+
|
|
178
|
+
stats.insert("total_scenarios".to_string(), self.scenario_history.len() as f32);
|
|
179
|
+
|
|
180
|
+
if !self.scenario_history.is_empty() {
|
|
181
|
+
let avg_impact: f32 = self.scenario_history
|
|
182
|
+
.iter()
|
|
183
|
+
.map(|s| s.impact_magnitude)
|
|
184
|
+
.sum::<f32>()
|
|
185
|
+
/ self.scenario_history.len() as f32;
|
|
186
|
+
|
|
187
|
+
let avg_confidence: f32 = self.scenario_history
|
|
188
|
+
.iter()
|
|
189
|
+
.map(|s| s.confidence)
|
|
190
|
+
.sum::<f32>()
|
|
191
|
+
/ self.scenario_history.len() as f32;
|
|
192
|
+
|
|
193
|
+
stats.insert("avg_impact".to_string(), avg_impact);
|
|
194
|
+
stats.insert("avg_confidence".to_string(), avg_confidence);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
stats
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
#[cfg(test)]
|
|
202
|
+
mod tests {
|
|
203
|
+
use super::*;
|
|
204
|
+
|
|
205
|
+
#[test]
|
|
206
|
+
fn test_scenario_creation() {
|
|
207
|
+
let scenario = CounterfactualScenario::new("test_scenario".to_string());
|
|
208
|
+
assert_eq!(scenario.name, "test_scenario");
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
#[test]
|
|
212
|
+
fn test_scenario_impact_score() {
|
|
213
|
+
let mut scenario = CounterfactualScenario::new("test".to_string());
|
|
214
|
+
scenario.impact_magnitude = 0.5;
|
|
215
|
+
scenario.confidence = 0.8;
|
|
216
|
+
|
|
217
|
+
assert_eq!(scenario.impact_score(), 0.4);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
#[test]
|
|
221
|
+
fn test_analyzer_creation() {
|
|
222
|
+
let baseline = HashMap::new();
|
|
223
|
+
let analyzer = ScenarioAnalyzer::new(baseline);
|
|
224
|
+
assert!(analyzer.scenario_history.is_empty());
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
#[test]
|
|
228
|
+
fn test_create_scenario() {
|
|
229
|
+
let baseline = {
|
|
230
|
+
let mut m = HashMap::new();
|
|
231
|
+
m.insert("feature1".to_string(), 0.5);
|
|
232
|
+
m
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
let mut analyzer = ScenarioAnalyzer::new(baseline);
|
|
236
|
+
let mut modifications = HashMap::new();
|
|
237
|
+
modifications.insert("feature1".to_string(), 0.8);
|
|
238
|
+
|
|
239
|
+
let scenario = analyzer.create_scenario("test".to_string(), modifications);
|
|
240
|
+
assert_eq!(scenario.affected_features.len(), 1);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
#[test]
|
|
244
|
+
fn test_analyze_cascade() {
|
|
245
|
+
let baseline = HashMap::new();
|
|
246
|
+
let analyzer = ScenarioAnalyzer::new(baseline);
|
|
247
|
+
|
|
248
|
+
let mut scenario = CounterfactualScenario::new("test".to_string());
|
|
249
|
+
scenario.modifications.insert("f1".to_string(), 1.0);
|
|
250
|
+
|
|
251
|
+
let mut causal_map = HashMap::new();
|
|
252
|
+
causal_map.insert("f1".to_string(), vec!["f2".to_string()]);
|
|
253
|
+
|
|
254
|
+
let effects = analyzer.analyze_cascade(&scenario, &causal_map);
|
|
255
|
+
assert!(effects.contains_key("f1"));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
#[test]
|
|
259
|
+
fn test_sensitivity_analysis() {
|
|
260
|
+
let baseline = {
|
|
261
|
+
let mut m = HashMap::new();
|
|
262
|
+
m.insert("feature1".to_string(), 0.5);
|
|
263
|
+
m
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
let mut analyzer = ScenarioAnalyzer::new(baseline);
|
|
267
|
+
let scenarios = analyzer.generate_sensitivity_analysis("feature1".to_string(), (0.0, 1.0), 5);
|
|
268
|
+
|
|
269
|
+
assert_eq!(scenarios.len(), 5);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
#[test]
|
|
273
|
+
fn test_compare_scenarios() {
|
|
274
|
+
let baseline = HashMap::new();
|
|
275
|
+
let analyzer = ScenarioAnalyzer::new(baseline);
|
|
276
|
+
|
|
277
|
+
let mut s1 = CounterfactualScenario::new("s1".to_string());
|
|
278
|
+
s1.modifications.insert("f1".to_string(), 0.5);
|
|
279
|
+
|
|
280
|
+
let mut s2 = CounterfactualScenario::new("s2".to_string());
|
|
281
|
+
s2.modifications.insert("f1".to_string(), 0.8);
|
|
282
|
+
|
|
283
|
+
let comparison = analyzer.compare_scenarios(&s1, &s2);
|
|
284
|
+
assert!(!comparison.is_empty());
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
#[test]
|
|
288
|
+
fn test_analyzer_statistics() {
|
|
289
|
+
let baseline = HashMap::new();
|
|
290
|
+
let mut analyzer = ScenarioAnalyzer::new(baseline);
|
|
291
|
+
|
|
292
|
+
let mut mods = HashMap::new();
|
|
293
|
+
mods.insert("f1".to_string(), 0.5);
|
|
294
|
+
analyzer.create_scenario("test".to_string(), mods);
|
|
295
|
+
|
|
296
|
+
let stats = analyzer.get_statistics();
|
|
297
|
+
assert_eq!(stats.get("total_scenarios"), Some(&1.0));
|
|
298
|
+
}
|
|
299
|
+
}
|