Files
tla_visualiser/docs/ARCHITECTURE.md
2025-12-27 02:56:19 +00:00

356 lines
9.3 KiB
Markdown

# Architecture Overview
This document describes the architecture and design of TLA+ Visualiser.
## High-Level Architecture
```
┌─────────────────────────────────────────────────────────┐
│ QML UI Layer │
│ (ImportView, GraphView, TraceView, InvariantView) │
└────────────────────┬────────────────────────────────────┘
│ Qt Signals/Slots
┌────────────────────▼────────────────────────────────────┐
│ Qt Models (QAbstractListModel) │
│ StateGraphModel TraceViewerModel │
└──────────┬──────────────────────┬───────────────────────┘
│ │
┌──────────▼──────────┐ ┌────────▼─────────────────────┐
│ GitHubImporter │ │ TLCRunner │
│ - URL parsing │ │ - Process management │
│ - HTTP requests │ │ - Output parsing │
│ - Local caching │ │ - Result serialization │
└─────────────────────┘ └──────────────────────────────┘
```
## Component Details
### 1. UI Layer (QML)
**Purpose**: Provides the user interface using Qt Quick/QML.
**Components**:
- `main.qml`: Application window, menu bar, tab navigation
- `ImportView.qml`: GitHub URL input and spec preview
- `GraphView.qml`: State/transition graph visualization
- `TraceView.qml`: Step-by-step trace inspection
- `InvariantView.qml`: Invariant status dashboard
**Communication**: Uses Qt's property binding and signal/slot mechanism to interact with C++ models.
### 2. Model Layer (Qt Models)
#### StateGraphModel
**Responsibility**: Provides data for state graph visualization.
**Key Methods**:
- `loadFromResults()`: Populate from TLC results
- `getTransitions()`: Return transition edges
- `getStateDetails()`: Get details for specific state
**Data**:
- States with positions (x, y coordinates)
- Transitions (edges between states)
- Layout calculated using circular algorithm
#### TraceViewerModel
**Responsibility**: Provides data for trace/counterexample viewing.
**Key Methods**:
- `loadTrace()`: Load a counterexample trace
- `exportToJson()`: Export trace as JSON
- `exportToMarkdown()`: Export trace as Markdown
**Data**:
- Sequence of trace steps
- Current step index
- Variable values at each step
### 3. Business Logic Layer
#### GitHubImporter
**Responsibility**: Fetch TLA+ specs from GitHub.
**Features**:
- **URL Parsing**: Regex-based parsing of GitHub URLs
- File URLs: `github.com/owner/repo/blob/branch/path`
- Raw URLs: `raw.githubusercontent.com/owner/repo/branch/path`
- Repo URLs: `github.com/owner/repo`
- **HTTP Communication**: Uses libcurl for HTTP requests
- Follows redirects
- Sets User-Agent header
- Error handling
- **Local Caching**: Saves fetched content to temp directory
- Cache key: `owner_repo_branch_filepath`
- Automatic cache lookup before fetching
**Design Pattern**: PIMPL (Pointer to Implementation)
- Public interface in header
- Private implementation in .cpp
- Hides libcurl details from API users
#### TLCRunner
**Responsibility**: Execute TLC model checker and parse results.
**Features**:
- **Process Management**: Runs TLC as external Java process
- Async execution in separate thread
- Cancellation support
- Status callbacks
- **Output Parsing**: Parses TLC text output
- State count extraction
- Error message collection
- Timing information
- **Result Persistence**: Save/load results
- Text-based format (upgradable to JSON)
- Deterministic runs
**States**:
- NotStarted
- Running
- Completed
- Failed
- Cancelled
**Design Pattern**: PIMPL + Observer (callbacks)
## Data Flow
### Import Flow
```
User enters URL
ImportView captures input
GitHubImporter.parseUrl()
GitHubImporter.fetchFile()
├─→ Check cache
└─→ HTTP request (libcurl)
Content displayed in ImportView
```
### Model Check Flow
```
User clicks "Run Model Checker"
TLCRunner.startModelCheck()
Spawn Java process (TLC)
Parse output in background thread
Update status via callback
TLCRunner.getResults()
StateGraphModel.loadFromResults()
TraceViewerModel.loadTrace()
UI updates via Qt property bindings
```
### Visualization Flow
```
User switches to Graph View
StateGraphModel provides data
├─→ Node positions (calculated)
├─→ Edge list
└─→ State details
QML Canvas or GraphicsView renders
User clicks node
Model provides details for selected node
```
## Design Patterns
### PIMPL (Pointer to Implementation)
Used in: `GitHubImporter`, `TLCRunner`, `StateGraphModel`, `TraceViewerModel`
**Benefits**:
- Binary compatibility (ABI stability)
- Faster compilation (hidden dependencies)
- Implementation flexibility
**Structure**:
```cpp
class MyClass {
public:
MyClass();
~MyClass();
void publicMethod();
private:
class Impl;
std::unique_ptr<Impl> pImpl;
};
```
### Observer Pattern
Used in: `TLCRunner` callbacks
**Benefits**:
- Async notification
- Decoupling
**Usage**:
```cpp
runner.setStatusCallback([](Status s) {
// Handle status change
});
```
### Model-View (Qt)
Used throughout for UI
**Benefits**:
- Separation of concerns
- Automatic updates
- Testable models
### Factory Pattern (Future)
Could be used for:
- Different graph layout algorithms
- Export format handlers
## Threading Model
### Main Thread
- Qt event loop
- UI updates
- User interaction
- Model data access
### Background Threads
- TLC execution (via `std::thread`)
- HTTP requests (via libcurl)
**Synchronization**: Qt signals/slots (thread-safe when queued)
## Memory Management
- **Smart Pointers**: `std::unique_ptr` for PIMPL idiom
- **Qt Parent-Child**: QObjects use Qt's parent-child ownership
- **RAII**: Resources cleaned up in destructors
- **No Manual new/delete**: Prefer stack allocation or smart pointers
## Error Handling
### Current Strategy
- Return values (bool for success/failure)
- Empty returns for errors (empty string, empty vector)
- Error messages stored in result structures
### Future Improvements
- Exception-based error handling
- Error codes enumeration
- Detailed error context
## Dependencies
### External Libraries
- **Qt 6**: UI framework, models, networking
- **libcurl**: HTTP requests
- **C++ Standard Library**: Containers, threading, filesystem
### Dependency Management
- **Conan**: Package manager for libcurl
- **CMake**: Build system integration
- **Find Modules**: Qt6 via CMake's built-in finder
## Extensibility Points
### Adding New Visualizations
1. Create new QML view (e.g., `TimelineView.qml`)
2. Create corresponding Qt model (e.g., `TimelineModel`)
3. Add tab in `main.qml`
4. Load data from `TLCRunner::RunResults`
### Adding New Import Sources
1. Create new importer class (e.g., `GitLabImporter`)
2. Implement common interface
3. Add UI option to select source
4. Integrate in `ImportView`
### Adding New Export Formats
1. Add export method to model (e.g., `exportToXML()`)
2. Add UI button/menu item
3. Implement serialization logic
## Testing Strategy
### Unit Tests
- **GitHubImporter**: URL parsing, cache operations
- **TLCRunner**: Status management, result saving
- **Models**: Data loading, transformations
### Integration Tests (Future)
- End-to-end import flow
- TLC execution with sample specs
- Export functionality
### UI Tests (Future)
- QML test framework
- Automated UI interaction
## Performance Considerations
### Current Optimizations
- Circular layout O(n) complexity
- Local caching to avoid redundant downloads
- Async TLC execution
### Future Optimizations
- Lazy loading for large graphs
- Level-of-detail rendering
- Progressive result display
- Worker threads for layout calculation
## Security Considerations
### Current Measures
- No credential storage
- Read-only spec access
- Local cache in temp directory
### Future Improvements
- GitHub token authentication (optional)
- HTTPS certificate validation
- Input sanitization for TLC invocation
- Sandboxed TLC execution
## Build System
### CMake Configuration
- Minimum version: 3.22
- C++20 standard requirement
- Qt6 modules: Core, Gui, Quick, Widgets
- Conan integration via toolchain file
### Platform Support
- **Linux**: Native builds, ARM64 via QEMU
- **macOS**: Native builds (x86_64, arm64)
- **Windows**: MSVC and MinGW support
### CI/CD
- GitHub Actions workflows
- Multi-platform builds
- Automated testing
- Artifact uploads
## Future Architecture Improvements
1. **Plugin System**: Allow third-party visualizations
2. **Async I/O**: libuv or Boost.Asio for better performance
3. **Database**: SQLite for result persistence
4. **Language Server**: TLA+ LSP integration
5. **Web Backend**: Optional web UI via REST API