mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
208 lines
7.7 KiB
Python
208 lines
7.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
OTOM LeanGPT Pipeline
|
|
Integrates LeanGPT framework as testing pipeline for OTOM Lean modules
|
|
|
|
Per AGENTS.md §6.1: Python shim for testing pipeline only
|
|
"""
|
|
|
|
import subprocess
|
|
import json
|
|
import logging
|
|
from pathlib import Path
|
|
from typing import Dict, List, Optional
|
|
from dataclasses import dataclass, asdict
|
|
from datetime import datetime
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger("OTOMLeanGPTPipeline")
|
|
|
|
@dataclass
|
|
class LeanModule:
|
|
"""OTOM Lean module for testing"""
|
|
name: str
|
|
path: str
|
|
domain: str
|
|
theorems: int
|
|
status: str # "complete", "wip", "todo"
|
|
|
|
@dataclass
|
|
class TestResult:
|
|
"""Test result for a Lean module"""
|
|
module: str
|
|
lake_build: bool
|
|
theorems_checked: int
|
|
errors: List[str]
|
|
duration: float
|
|
timestamp: str
|
|
|
|
class OTOMLeanGPTPipeline:
|
|
"""
|
|
Integrates LeanGPT framework for testing OTOM Lean modules.
|
|
|
|
Pipeline:
|
|
1. Lake build check (compilation)
|
|
2. Theorem verification
|
|
3. AI-assisted proof generation (future)
|
|
"""
|
|
|
|
def __init__(self, lean_path: str = None, lean_gpt_path: str = None):
|
|
self.lean_path = Path(lean_path) if lean_path else Path("/home/allaun/Documents/Research Stack/0-Core-Formalism/lean/Semantics")
|
|
self.lean_gpt_path = Path(lean_gpt_path) if lean_gpt_path else Path("/home/allaun/Documents/Research Stack/0-Core-Formalism/lean/LeanGPT")
|
|
self.results: List[TestResult] = []
|
|
|
|
# OTOM v2.1 modules
|
|
self.modules = [
|
|
LeanModule("GenomicCompression", "Semantics/GenomicCompression.lean", "Compression", 4, "complete"),
|
|
LeanModule("ResearchAgent", "Semantics/ResearchAgent.lean", "Cognitive/Control", 4, "complete"),
|
|
LeanModule("CrossModalCompression", "Semantics/CrossModalCompression.lean", "Compression", 2, "complete"),
|
|
LeanModule("AgenticOrchestration", "Semantics/AgenticOrchestration.lean", "Cognitive/Control", 0, "complete"),
|
|
LeanModule("BracketShellCount", "Semantics/BracketShellCount.lean", "Braid/Algebra", 2, "wip"),
|
|
]
|
|
|
|
logger.info(f"OTOM LeanGPT Pipeline initialized")
|
|
logger.info(f"Lean path: {self.lean_path}")
|
|
logger.info(f"LeanGPT path: {self.lean_gpt_path}")
|
|
|
|
def lake_build_module(self, module: LeanModule) -> tuple[bool, List[str], float]:
|
|
"""Run lake build on the entire Semantics package"""
|
|
start_time = datetime.now()
|
|
module_path = self.lean_path / module.path
|
|
|
|
if not module_path.exists():
|
|
return False, [f"Module not found: {module_path}"], 0.0
|
|
|
|
try:
|
|
# Build the entire Semantics package
|
|
result = subprocess.run(
|
|
["lake", "build"],
|
|
cwd=self.lean_path,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=300 # 5 minute timeout for full build
|
|
)
|
|
|
|
duration = (datetime.now() - start_time).total_seconds()
|
|
success = result.returncode == 0
|
|
|
|
errors = []
|
|
if not success:
|
|
# Extract last 500 chars of stderr for error reporting
|
|
stderr_lines = result.stderr.split('\n')
|
|
error_lines = [line for line in stderr_lines if 'error:' in line.lower()]
|
|
if error_lines:
|
|
errors.append('\n'.join(error_lines[-5:])) # Last 5 error lines
|
|
else:
|
|
errors.append(result.stderr[-500:] if len(result.stderr) > 500 else result.stderr)
|
|
|
|
return success, errors, duration
|
|
|
|
except subprocess.TimeoutExpired:
|
|
duration = (datetime.now() - start_time).total_seconds()
|
|
return False, ["Build timeout after 300s"], duration
|
|
except Exception as e:
|
|
duration = (datetime.now() - start_time).total_seconds()
|
|
return False, [f"Build error: {str(e)}"], duration
|
|
|
|
def check_theorems(self, module: LeanModule) -> int:
|
|
"""
|
|
Check theorems in a module (placeholder for LeanGPT integration).
|
|
|
|
In full implementation, this would:
|
|
1. Parse the module for theorem declarations
|
|
2. Check which have proofs vs sorry
|
|
3. Use LeanGPT to attempt proof generation for sorry placeholders
|
|
"""
|
|
# Placeholder: use Grep to find theorems
|
|
# For now, return the expected count from module definition
|
|
return module.theorems
|
|
|
|
def run_test(self, module: LeanModule) -> TestResult:
|
|
"""Run full test on a module"""
|
|
logger.info(f"Testing module: {module.name}")
|
|
|
|
# Step 1: Lake build
|
|
build_success, build_errors, build_duration = self.lake_build_module(module)
|
|
|
|
# Step 2: Check theorems
|
|
theorems_checked = self.check_theorems(module)
|
|
|
|
result = TestResult(
|
|
module=module.name,
|
|
lake_build=build_success,
|
|
theorems_checked=theorems_checked,
|
|
errors=build_errors,
|
|
duration=build_duration,
|
|
timestamp=datetime.now().isoformat()
|
|
)
|
|
|
|
self.results.append(result)
|
|
logger.info(f"Test complete: {module.name} - Success: {build_success}")
|
|
|
|
return result
|
|
|
|
def run_pipeline(self) -> Dict:
|
|
"""Run full OTOM pipeline test"""
|
|
logger.info("=" * 60)
|
|
logger.info("OTOM LEANGPT PIPELINE")
|
|
logger.info("=" * 60)
|
|
|
|
for module in self.modules:
|
|
self.run_test(module)
|
|
|
|
# Summary statistics
|
|
total_modules = len(self.modules)
|
|
successful_builds = sum(1 for r in self.results if r.lake_build)
|
|
total_theorems = sum(r.theorems_checked for r in self.results)
|
|
total_errors = sum(len(r.errors) for r in self.results)
|
|
|
|
summary = {
|
|
"total_modules": total_modules,
|
|
"successful_builds": successful_builds,
|
|
"build_success_rate": successful_builds / total_modules if total_modules > 0 else 0,
|
|
"total_theorems": total_theorems,
|
|
"total_errors": total_errors,
|
|
"results": [asdict(r) for r in self.results],
|
|
"timestamp": datetime.now().isoformat()
|
|
}
|
|
|
|
# Save results
|
|
results_file = self.lean_gpt_path / "otom_test_results.json"
|
|
with open(results_file, 'w') as f:
|
|
json.dump(summary, f, indent=2)
|
|
|
|
logger.info(f"\nPipeline complete. Results saved to {results_file}")
|
|
|
|
return summary
|
|
|
|
def print_summary(self, summary: Dict):
|
|
"""Print test summary"""
|
|
print("\n" + "=" * 60)
|
|
print("OTOM LEANGPT PIPELINE RESULTS")
|
|
print("=" * 60)
|
|
print(f"Total modules: {summary['total_modules']}")
|
|
print(f"Successful builds: {summary['successful_builds']}/{summary['total_modules']}")
|
|
print(f"Build success rate: {summary['build_success_rate']:.2%}")
|
|
print(f"Total theorems: {summary['total_theorems']}")
|
|
print(f"Total errors: {summary['total_errors']}")
|
|
|
|
print("\nModule Results:")
|
|
print("-" * 60)
|
|
for result in summary['results']:
|
|
status = "✓" if result['lake_build'] else "✗"
|
|
print(f"{status} {result['module']:20} | Theorems: {result['theorems_checked']:2} | Duration: {result['duration']:6.2f}s")
|
|
if result['errors']:
|
|
for error in result['errors'][:2]:
|
|
print(f" Error: {error}")
|
|
|
|
print("=" * 60)
|
|
|
|
# CLI interface
|
|
if __name__ == "__main__":
|
|
print("=" * 60)
|
|
print("OTOM LEANGPT PIPELINE")
|
|
print("=" * 60)
|
|
|
|
pipeline = OTOMLeanGPTPipeline()
|
|
summary = pipeline.run_pipeline()
|
|
pipeline.print_summary(summary)
|