CoCoPath is a concolic execution framework for systematically exploring execution paths in consistency-preserving model transformations. By combining dynamic taint tracking, concolic execution, and model transformation frameworks, CoCoPath enables automatic path exploration to derive potential target models based on source models, consistency preservation rules (CPRs), and optional domain constraints.
This project integrates:
- Galette - Dynamic taint tracking for the JVM
- Modified Knarr Runtime - Symbolic execution engine
- Z3 Solver - SMT constraint solver (via JNI)
- Vitruvius Framework - Model transformation and consistency preservation
The framework provides concolic execution (combined concrete + symbolic execution) for model transformations, enabling developers to explore the consequences of different user decisions and resolve temporary inconsistencies in an informed manner.
- Executes transformations with concrete input values
- Tracks symbolic values through transformation logic via dynamic taint tracking
- Collects path constraints from consistency preservation rules
- Generates new inputs by negating constraints and solving with Z3
- Explores all feasible paths automatically until complete
- Purpose: Propagates symbolic tags through JVM bytecode execution
- Role: Attaches and propagates symbolic identities alongside concrete values
- Key APIs:
Tainter.setTag(value, tag)- Attach symbolic tag to valueTainter.getTag(value)- Retrieve tag from value- Tag propagation through arithmetic, method calls, field access
- Purpose: Symbolic execution and path constraint management
- Location:
knarr-runtime/src/main/java/edu/neu/ccs/prl/galette/ - Key Classes:
GaletteSymbolicator- Creates and manages symbolic values with tag reusePathExplorer- Orchestrates systematic path explorationPathUtils- Manages path conditions and constraintsSymbolicComparison- Records constraints from Vitruvius reactionsZ3ConstraintSolver- Interfaces with Z3 for constraint solving
- Purpose: Provides real-world model transformation scenarios
- Example: AMALTHEA ↔ ASCET model synchronization
- Location:
amalthea-acset-integration/ - Consistency preservation rules require user decisions that cannot be resolved automatically
CoCoPath employs a CPR-level constraint registration mechanism that makes decision semantics explicit at the transformation logic level:
- Symbolic Variable Registration: Vitruvius reactions call
GaletteSymbolicator.getOrMakeSymbolicInt()to create or reuse symbolic tags - Constraint Recording: Reactions invoke
SymbolicComparison.symbolicVitruviusChoice()to record path constraints - Tag Reuse: Qualified names (e.g., "CreateAscetTaskRoutine:execute:userChoice_forTask_task1") enable tag reuse across iterations
This approach prioritizes framework compatibility and reliability over full automation, avoiding bytecode verification issues while maintaining systematic path exploration capabilities.
CocoPath/
├── knarr-runtime/
│ ├── src/main/java/
│ │ └── edu/neu/ccs/prl/galette/
│ │ ├── concolic/knarr/runtime/
│ │ │ ├── GaletteSymbolicator.java # Symbolic value creation with tag reuse
│ │ │ ├── PathExplorer.java # Systematic path exploration
│ │ │ ├── PathUtils.java # Path constraint management
│ │ │ ├── SymbolicComparison.java # Constraint recording from reactions
│ │ │ └── Z3ConstraintSolver.java # Z3 SMT solver integration
│ │ └── vitruvius/
│ │ ├── AutomaticVitruvPathExploration.java # Single-variable exploration
│ │ └── AutomaticVitruvMultiVarPathExploration.java # Multi-variable exploration
│ └── run-symbolic-execution.sh # Execution scripts
│
├── amalthea-acset-integration/ # Vitruvius case study
│ ├── vsum/src/main/java/.../Test.java # Model transformation entry point
│ └── consistency/src/main/reactions/ # Consistency preservation rules
│
└── README.md # This file
- Java 17 (OpenJDK recommended for building, supports Java 8-21 at runtime)
- Maven 3.6+
- Python 3.x (for dependency management scripts)
- Z3 Solver (included via z3-turnkey dependency)
- Git (for cloning external dependencies)
# Clone the external Amalthea-ASCET repository (required for Vitruvius)
cd /home/anne/CocoPath
git clone https://github.com/IngridJiang/Amalthea-acset.git
# Build it to populate Maven repository
cd Amalthea-acset
mvn clean install -DskipTests -Dcheckstyle.skip=truecd /home/anne/CocoPath/CocoPath
mvn clean install -DskipTests -Dcheckstyle.skip=truecd knarr-runtime
mvn process-test-resourcesImportant: The instrumented Java VM at target/galette/java/ is required for dynamic taint tracking.
cd knarr-runtime
# Interactive mode - choose execution type
./run-symbolic-execution.sh
# Direct execution modes:
./run-symbolic-execution.sh --internal # Simplified test case
./run-symbolic-execution.sh --external # Full Vitruvius transformations
./run-symbolic-execution.sh --multivar # Multi-variable exploration (25 paths)Windows:
run-symbolic-execution.bat
run-symbolic-execution.bat internal
run-symbolic-execution.bat multivarPowerShell:
.\run-symbolic-execution.ps1
.\run-symbolic-execution.ps1 -Internal
.\run-symbolic-execution.ps1 -MultiVar- Explores one symbolic user decision with 5 possible values
- Generates 5 execution paths
- Output:
execution_paths_automatic.jsonand model files ingalette-output-automatic-{0..4}/
- Explores TWO symbolic user decisions simultaneously
- Generates 25 execution paths (5 × 5 combinations)
- Output:
execution_paths_multivar.jsonand models ingalette-output-multivar-{i}_{j}/
knarr-runtime/
├── execution_paths_automatic.json # Single-variable: 5 paths with constraints
├── execution_paths_multivar.json # Multi-variable: 25 path combinations
├── galette-output-automatic-*/ # Generated models per path
└── galette-output-multivar-*_*/ # Models for each input combination
└── galette-test-output/
└── vsum-output.xmi # Synchronized AMALTHEA+ASCET models
Each path record contains:
- pathId: Unique path identifier
- inputs: Concrete values for symbolic variables
- constraints: Path conditions as logical formulas
- executionTime: Performance metrics
The evaluated scenario demonstrates consistency preservation between:
- AMALTHEA: Models ECU architecture and operating system aspects
- ASCET: Specifies functional behavior of embedded control systems
When adding a Task to AMALTHEA, the CPR must create a corresponding task in ASCET. However, ASCET defines multiple concrete task subtypes (InitTask, PeriodicTask, SoftwareTask, TimeTableTask) while AMALTHEA uses abstract Tasks. This mapping requires domain knowledge and user decisions.
To modify the reactions or experiment with different transformation logic:
-
Clone the external AMALTHEA-ASCET repository:
git clone https://github.com/IngridJiang/Amalthea-acset
-
Modify the reactions in the external project and generate Java code:
cd Amalthea-acset mvn clean generate-sources -
Copy generated reactions to the internal CoCoPath project:
cd /path/to/CocoPath/knarr-runtime ./copy-generated-reactions.sh --external-path /path/to/Amalthea-acset -
Rebuild the internal project with updated reactions:
cd ../amalthea-acset-integration mvn clean compile -Dcheckstyle.skip=true
The copy-generated-reactions.sh script copies generated Java code from:
- Source:
Amalthea-acset/consistency/target/generated-sources/reactions/mir/ - Target:
amalthea-acset-integration/consistency/src/main/java/mir/
CoCoPath systematically explores all possible mappings, generating:
- Target ASCET models for each choice
- Model difference metrics (added/modified/deleted elements)
- Path constraints characterizing each execution
This enables engineers to:
- Compare transformation outcomes quantitatively
- Identify high-impact decision points
- Understand consequences before committing changes
Problem: "Instrumented java not found at target/galette/java/bin/java"
# Solution: Force regeneration of instrumented Java
cd knarr-runtime
rm -rf target/galette/
mvn clean process-test-resourcesProblem: "Existing Java installation did not have correct settings"
- This occurs when the instrumented Java was built with different settings
- The Galette Maven plugin will automatically delete and recreate it
Problem: Conflicting dependency versions or stale artifacts
# Solution 1: Clean local Maven cache for the project
rm -rf ~/.m2/repository/edu/neu/ccs/prl/galette/
rm -rf ~/.m2/repository/tools/vitruv/methodologisttemplate/
# Solution 2: Force update dependencies
mvn clean install -U -DskipTestsProblem: Missing CreateInterruptTaskRoutine or compilation errors
# Solution: Regenerate reactions from scratch
cd /home/anne/CocoPath/Amalthea-acset
mvn clean generate-sources
mvn install -DskipTests -Dcheckstyle.skip=true
# Then copy to internal project
cd /home/anne/CocoPath/CocoPath/knarr-runtime
./copy-generated-reactions.sh --external-path /home/anne/CocoPath/Amalthea-acsetProblem: UnsatisfiedLinkError for Z3 native library
- The z3-turnkey dependency should handle this automatically
- If issues persist, verify Z3 native libs are present:
ls ~/.m2/repository/tools/aqua/z3-turnkey/4.12.2.1/
# Should contain native libraries for your platformProblem: "var cannot be resolved to a type" or similar Java feature errors
- Ensure JAVA_HOME points to Java 17+:
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
java -version # Should show 17.x.xAfter setup, verify everything works:
# 1. Check Java version
java -version | grep "17"
# 2. Check Galette agent exists
ls ~/.m2/repository/edu/neu/ccs/prl/galette/galette-agent/1.0.0-SNAPSHOT/
# 3. Check instrumented Java exists
ls knarr-runtime/target/galette/java/bin/java
# 4. Run simple internal test
cd knarr-runtime
./run-symbolic-execution.sh --internal
# 5. Check output was generated
ls execution_paths_automatic.json
ls -d galette-output-automatic-*/- Tag Creation:
GaletteSymbolicator.getOrMakeSymbolicInt(qualifiedName, value, min, max) - Tag Reuse: Qualified names enable consistent symbolic variables across iterations
- Expression Mapping: Tags are associated with Green/Z3 expressions for solving
- Domain Constraints: Define valid value ranges (e.g.,
0 <= userChoice < 5) - Path Constraints: Record executed branches (e.g.,
userChoice == 2) - Negation Strategy: Systematically negate constraints to explore alternative paths
- Initialize with concrete input values
- Execute transformation while collecting constraints
- Negate selected constraints to generate new inputs
- Solve constraint system with Z3
- Re-execute with new inputs if satisfiable
- Terminate when no unexplored feasible paths remain
Based on the ECMFA-20 paper evaluation:
- Path Coverage: Achieves complete systematic exploration (5/5 single-variable, 25/25 multi-variable paths)
- Scalability: Per-path execution time increases only 1.42× despite 5× increase in paths
- Memory Overhead: Moderate 1.36× overhead, primarily from dynamic taint tracking
- Compatibility: Only symbolic execution tool fully compatible with Vitruvius/EMF/OSGi
- Manual Constraint Registration: Requires explicit constraint recording in CPRs (future work: automatic weaving)
- Third-party Libraries: Cannot track decisions in external code
- Runtime Overhead: Dynamic taint tracking introduces performance cost
- Domain Constraints: Must be manually specified based on domain knowledge
- Bytecode-level constraint extraction for full automation
- Support for additional transformation frameworks beyond Vitruvius
- Optimization of taint tracking overhead
- Integration with model verification techniques
See LICENSE in the project root.
- Galette: Northeastern University (Dynamic Taint Tracking)
- Knarr: Original symbolic execution engine (modified for Galette integration)
- Z3: Microsoft Research (SMT Solver)
- Vitruvius: Karlsruhe Institute of Technology (Model Transformation Framework)
- AMALTHEA-ASCET: Bosch (Industrial case study)
