TwinCompass is a powerful neuro-symbolic, multi-reasoning decision-making framework designed to intelligently support the selection of digital twin technologies, tools, and standards across complex engineering environments. TwinCompass uses a comprehensive multi-reasoning mechanisms that assists users in selecting the most appropriate tools, technologies, and standards across the Digital Twin Spectrum. By leveraging structured XML feature models, large language models (LLMs), AHP, TOPSIS, and Prolog reasoning, the framework enables intelligent, traceable, and explainable recommendations.
- Quick Start
- What is TwinCompass?
- Architecture Overview
- Key Components
- Installation & Setup
- Environment Variables
- Usage Guide
- Defining Constraints with Prolog
- Project Structure
- API Reference
- Examples
- Troubleshooting
- FAQ
- Performance Metrics
- Production Readiness
- Contributing
- License
- Authors
- Related Resources
- Python 3.10 or higher
- Node.js 14+ and npm 6+
- Git
# Clone the repository
git clone https://github.com/husseinmarah/dt-recommender
cd dt-recommender
# Install Python dependencies
pip install -r requirements.txtQuick Start (All Platforms):
# From the project root directory
python start_app.pyThis single command starts:
- β TwinCompass Engine - Main recommendation system
- β
Frontend - React/Next.js UI on
http://localhost:3000 - β
Backend - Flask API on
http://localhost:5000
Alternative: Manual Start (Multiple Terminals)
# Terminal 1: Frontend UI
cd web_app/frontend
npm install
npm run devTwinCompass is an intelligent recommendation system that solves a complex problem: Given a Digital Twin project with specific goals and constraints, which technologies should we use?
Selecting technologies for Digital Twin systems involves:
- β Providing informed recommendations about the Digital Twin engineering landscape
- β Evaluating dozens of design, engineering, and modelling alternatives
- β Balancing conflicting requirements across multiple dimensions
- β Checking complex dependency constraints
- β Ensuring compatibility between selected components
- β Documenting decision rationale for stakeholders
Without TwinCompass: Manual evaluation is time-consuming, inconsistent, and error-prone.
With TwinCompass: Structured, explainable, constraint-validated recommendations in minutes.
User Input (Goals & Preferences)
β
XML Feature Models (Alternatives & Criteria)
β
LLM-Assisted Weighting (Via AHP)
β
TOPSIS Ranking (Top Candidates)
β
Prolog Validation (Constraint Checking)
β
Explainable Recommendations
TwinCompass uses a modular architecture combining multiple reasoning approaches:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TwinCompass System β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββ
β β β
βββββββΌβββββ βββββββΌβββββ βββββββΌββββββ
β AHP β β TOPSIS β β Prolog β
β Weightingβ β Ranking β β Validationβ
ββββββββββββ ββββββββββββ βββββββββββββ
β β β
LLM Integration Feature Models DSL Rules
(GPT-4, etc.) (XML Files) (JSONβProlog)
- XML Feature Models Processing (
xml_processing/*.py): Parses XML feature models from DT Design Feature Models and extracts alternatives and criteria - AHP Module (
mcda/ahp.py): Analytical Hierarchy Process for weighted criteria - TOPSIS Module (
mcda/topsis.py): Ranking alternatives by ideal/anti-ideal proximity - LLM Integration (
llm_models/llm.py): Contextual reasoning and weighting - Prolog Reasoner (
reasoner/prolog_reasoner.py): Constraint validation
- Location:
web_app/(in dt-recommender) - Frontend (
web_app/frontend/): React/Next.js web interface for TwinCompass recommendations - Backend (
web_app/backend/): Flask API server for TwinCompass engine - Purpose: User interface for accessing TwinCompass recommendation system
- Port: Frontend runs on port 3000, Backend on port 5000
- Location:
./json-2-prolog-editor - Repository: json-2-prolog-editor
- Purpose: Monaco Editor-based UI for writing DSL rules and converting to Prolog
- Integration: Communicates with TwinCompass Prolog Generator backend
- Repository: dt-design-recommendation-dataset
- Purpose: XML-based feature models defining Digital Twin technology alternatives and criteria
- Integration: Feature models are parsed by TwinCompass for recommendation generation
# From the dt-recommender project root
python start_app.pyThis script automatically:
- β Installs all dependencies (Python & Node.js)
- β Creates Python virtual environments
- β Starts TwinCompass engine
- β Starts React/Next.js frontend (port 3000)
- β Starts Flask backend (port 5000)
- β Starts Prolog Generator backend
Note: The Prolog DSL Editor is a separate project. After starting TwinCompass with start_app.py, you can also run the DSL Editor from json-2-prolog-editor repository to create custom rules.
# Navigate to project
cd dt-recommender
# Create virtual environment
python -m venv venv
# Activate
# Windows:
venv\Scripts\activate
# macOS/Linux:
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt# Run tests
python -m pytest tests/
# Example output (current)
# 17 passed in ~1.5s
# Run linting
pylint **/*.pyCreate a .env file in the project root (dt-recommender/.env) before running the CLI or web app.
Required variables:
OPENAI_API_KEY: Your OpenAI API key used by the LLM integration.GIT_REPO_PATH: Dataset base URL from the feature-model repository.CORS_ALLOW_ORIGINS: Comma-separated frontend origins allowed to call backend API (for example:https://app.example.com,https://admin.example.com).
Example .env:
OPENAI_API_KEY=your_openai_api_key_here
GIT_REPO_PATH=https://github.com/husseinmarah/dt-design-recommendation-dataset/tree/main/dataset/Notes:
- Keep
.envprivate and never commit it. - Do not wrap values with quotes unless needed.
- If
GIT_REPO_PATHis not set, the app may fail during startup when loading XML models. - In production, avoid
CORS_ALLOW_ORIGINS=*; set explicit trusted origins.
The Prolog DSL Editor and Prolog Code Generator are maintained in a separate repository: TwinCompass Prolog DSL. Refer to that repository for setup and usage instructions. The repository includes both the DSL Editor UI and the Prolog code generation backend.
The easiest way that automate how to start TwinCompass (GUI):
# From project root
python start_app.pyThis automatically configures and starts:
- TwinCompass recommendation engine
- React/Next.js frontend (http://localhost:3000)
- Flask backend API (http://localhost:5000)
TwinCompass is an interactive CLI application. Start it with:
# From project root
python main.pyInteractive Menu:
The application presents a main menu with options:
ββββββββββββββββββββββββββββββββββββββββββββββ
β TwinCompass - Main Menu β
ββββββββββββββββββββββββββββββββββββββββββββββ€
β 1. Goal & Purpose Recommendations β
β 2. Architecture Recommendations β
β 3. Formalisms & Deployment Recommendations β
β 4. Standards Recommendations β
β 5. Exit β
ββββββββββββββββββββββββββββββββββββββββββββββ
Workflow:
- Select a recommendation category (1-4)
- Navigate the feature model tree using interactive prompts
- Provide a description of your requirements
- TwinCompass performs:
- AHP: Weighted criteria calculation (manual or LLM-assisted)
- TOPSIS: Ranks alternatives by ideal/anti-ideal proximity
- Prolog Validation: Checks constraints and dependencies
- View ranked recommendations with conflict/dependency warnings
Example: Getting Architecture Recommendations
$ python main.py
Manual AHP Pairwise Comparison? (y/n): n
Select an option:
1. Goal & Purpose Recommendations
2. Architecture Recommendations
3. Formalisms & Deployment Recommendations
4. Standards Recommendations
5. Exit
Enter your choice (1-5): 2
# Interactive navigation through architecture model...
# Provide your requirements...
# View AHP weights, TOPSIS ranking, and Prolog constraint validationEdit DSL rules to define:
- alternatives: What choices are available
- requires: Mandatory dependencies
- recommends: Optional suggestions
- mutual_exclusive: Conflicting options
- group_dependency: Items that must be selected together
Prolog is a declarative logic programming language where you describe what the problem is, not how to solve it. The Prolog engine uses logical inference (unification + backtracking) to find solutions.
| Relationship | Meaning | Example |
|---|---|---|
alternative(Parent, Child) |
Choice: Parent can be one of several children | alternative(arch, microservices) |
requires(A, B) |
Mandatory: Selecting A requires B | requires(microservices, kubernetes) |
recommends(A, B) |
Optional: A recommends B | recommends(microservices, api_gateway) |
mutual_exclusive(A, B) |
Conflict: A and B cannot coexist | mutual_exclusive(monolith, microservices) |
group_dependency(A, B) |
Group: All B items must be selected with A | group_dependency(tier1, feature1) |
% Find all deployment options
?- alternative(deployment, X).
% Output: X = cloud; X = edge; X = on_premise
% Check if a dependency is satisfied
?- requires(microservices, kubernetes).
% Output: true
% Find what requires Kubernetes
?- requires(X, kubernetes).
% Output: X = microservices
% Validate: Can we select both monolith and microservices?
?- mutual_exclusive(monolith, microservices).
% Output: true (violation!)dt-recommender/
βββ llm_models/
β βββ __init__.py
β βββ llm.py # LLM integration (GPT-4, etc.)
β
βββ mcda/ # Multi-Criteria Decision Analysis
β βββ __init__.py
β βββ ahp.py # Analytical Hierarchy Process
β βββ topsis.py # TOPSIS algorithm
β
βββ reasoner/ # Logical Reasoning Engine
β βββ __init__.py
β βββ prolog_reasoner.py # Prolog constraint validation
β
βββ xml_processing/ # Feature Model Processing
β βββ __init__.py
β βββ xml_parser.py # XML parsing
β βββ xml_extractor.py # Data extraction
β βββ xml_metrics.py # Metrics analysis
β βββ ...
β
β
βββ utilities/ # Helper Utilities
β βββ __init__.py
β βββ util.py
β βββ visualizer.py
β
βββ tests/ # Testing & Benchmarking
β βββ benchmark.py
β βββ evaluation.py
β βββ pairwise.py
β
βββ data/ # Data Files
β βββ *.csv # Benchmark data
β
βββ files/
β βββ rules.pl # Generated Prolog rules (from json-2-prolog-editor)
β
βββ main.py # TwinCompass core engine
βββ start_app.py # Main entry point (starts all components)
βββ requirements.txt # Python dependencies
βββ pyproject.toml # Project configuration
βββ README.md # This file
from mcda.ahp import build_pairwise_matrix, compute_priority_vector, calculate_consistency_ratio
# Build pairwise comparison matrix from LLM-generated JSON
pairwise_matrix = build_pairwise_matrix(llm_json, criteria)
# Compute priority vector (weights) from pairwise comparison
priority_vector = compute_priority_vector(pairwise_matrix)
# Calculate consistency ratio to validate the matrix
consistency_ratio = calculate_consistency_ratio(pairwise_matrix, priority_vector)from mcda.topsis import create_decision_matrix, create_weights_dict, create_criteria_list
# Create weights dictionary from criteria and weights
criteria_weights = create_weights_dict(['Performance', 'Cost', 'Scalability'], [0.5, 0.3, 0.2])
# Create decision matrix from alternatives, criteria, and LLM-assisted scoring
decision_matrix = create_decision_matrix(
alternatives=['Option1', 'Option2'],
criteria_list=['Performance', 'Cost', 'Scalability'],
user_description='...',
attributes_info={...},
criteria_weights=criteria_weights
)from reasoner.prolog_reasoner import initialize_prolog, get_conflicts, get_mandatory_selections
# Initialize Prolog with a knowledge base
prolog = initialize_prolog('files/rules.pl')
# Check for conflicts between alternatives
conflicts = get_conflicts(prolog, 'microservices')
# Get mandatory selections for an alternative
mandatory = get_mandatory_selections(prolog, 'microservices')# From project root
python main.pyThis starts the interactive flow implemented in main.py (start_wise_twin()), including:
- XML navigation and selection (
xml_processing/xml_extractor.py) - AHP weighting (
call_ahpinmain.py) - TOPSIS ranking (
call_topsisinmain.py) - Prolog conflict/dependency/recommendation checks (
reasoner/prolog_reasoner.py)
from xml_processing.xml_parser import parse_xml, extract_children_criteria
from utilities.util import get_folder_path
# Load one of the feature models using the same base path used by the app
root = parse_xml(get_folder_path() + "architecture_model_v0.1.xml")
# Extract criteria from direct children of the current root
criteria = extract_children_criteria(root)
print(criteria)from mcda.ahp import build_pairwise_matrix, compute_priority_vector, calculate_consistency_ratio
criteria = ["Performance", "Cost", "Scalability"]
# Nested-dictionary format supported by build_pairwise_matrix()
pairwise = {
"Performance": {"Performance": 1.0, "Cost": 3.0, "Scalability": 2.0},
"Cost": {"Performance": 1/3, "Cost": 1.0, "Scalability": 1/2},
"Scalability": {"Performance": 1/2, "Cost": 2.0, "Scalability": 1.0},
}
matrix = build_pairwise_matrix(pairwise, criteria)
_, weights = compute_priority_vector(matrix)
consistency_ratio, *_ = calculate_consistency_ratio(matrix, weights)
print("Weights:", weights)
print("Consistency Ratio:", consistency_ratio)from mcda.topsis import create_weights_dict, create_criteria_list
filtered_criteria = ["Performance", "Cost", "Scalability"]
priority_weights = [0.5, 0.2, 0.3]
criteria_weights = create_weights_dict(filtered_criteria, priority_weights)
criteria_list = create_criteria_list(filtered_criteria)
print(criteria_weights)
print(criteria_list)from reasoner.prolog_reasoner import initialize_prolog, get_conflicts, get_mandatory_selections, get_recommendation
prolog = initialize_prolog("files/rules.pl")
alternative = "Digital_Model"
print("Conflicts:", get_conflicts(prolog, alternative))
print("Mandatory:", get_mandatory_selections(prolog, alternative))
print("Recommendations:", get_recommendation(prolog, alternative))Solution:
# Find and kill process on port 3000 (Windows)
netstat -ano | findstr :3000
taskkill /PID <PID> /F
# macOS/Linux
lsof -i :3000
kill -9 <PID>Solution:
# Recreate virtual environment
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txtSolution:
# Set environment variable
# Windows
set OPENAI_API_KEY=your_key_here
# macOS/Linux
export OPENAI_API_KEY=your_key_hereSolution:
- Verify the Prolog code generator is running (see json-2-prolog-editor repository)
- Check generator logs for errors
- Verify JSON format in DSL Editor
- Ensure that the new exported rules are put in the correct Prolog folder in the project.
We welcome contributions! Please follow these guidelines:
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature - Commit changes with clear messages
- Push to the branch
- Submit a Pull Request with description
# Install development dependencies
pip install -r requirements-dev.txt
# Run tests
python -m pytest tests/
# Example output (current)
# 17 passed in ~1.5s
# Run linting
pylint **/*.pyQ: Can I use TwinCompass without LLMs? A: Yes! You can manually define criteria weights in the AHP step. LLMs are optional for automated reasoning.
Q: How do I update the feature models? A: Feature models are maintained in a separate repository: DT Design Feature Models Dataset. Clone that repository and use the XML files from there.
Q: Can I export recommendations to a report? A: Yes, the framework supports JSON export. You can then generate reports using your preferred tools.
Q: What's the typical recommendation time? A: Depend on the number of alternatives and criteria if LLM are used. If manual option is used then the time is <5 seconds.
Q: Can I use this for non-Digital-Twin domains? A: Absolutely! TwinCompass is generic for any multi-criteria decision-making problem.
| Operation | Time | Notes |
|---|---|---|
| Feature Model Parsing | <500ms | Single model |
| AHP Weighting (Manual) | <100ms | Fast matrix calculation |
| AHP Weighting (LLM) | seconds-minutes | Depends on LLM API and the number of options and criteria |
| TOPSIS Ranking | <200ms | Per 100 alternatives |
| Prolog Validation | <50ms | Typical ruleset |
| Full Recommendation | 2-6s | MCDM (Manual Weighting) + Logical Validation |
Before deploying to production, complete the project checklist:
Backend operational endpoints available for deployment probes:
GET /health: Liveness and runtime status summaryGET /ready: Readiness check for required environment and Prolog initialization
CI gates are implemented in:
.github/workflows/ci.yml
This work is licensed under a Creative Commons Attribution 4.0 International License.
You are free to:
- β Share and adapt the material
- β Use commercially and privately
Under the terms:
- π Must give appropriate credit
- π Provide a link to the license
- π Indicate if changes were made
Hussein Marah - Principal Developer and Researcher
For questions or suggestions, please open an issue on GitHub.


