This tool implements a benchmark framework for evaluating the ability of Large Language Models (LLMs) to suggest structural bindings for model-to-model transformations, using manually authored ATL (ATLAS Transformation Language) rules as ground truth. Given a source and target metamodel, an LLM is asked to propose class-level and feature-level correspondences — a task that a human expert would otherwise perform by writing an ATL transformation by hand. The tool extracts the authoritative binding structure from existing ATL programs, compares it against LLM-generated suggestions, and measures precision, recall, and accuracy at both the class-mapping and structural-feature-binding levels, with explicit treatment of partial matches arising from helper-based bindings.
Model-to-model (M2M) transformation is a foundational activity in Model-Driven Engineering (MDE). In the ATL language, a transformation encodes correspondences between two metamodels: each matched rule declares which source metaclass maps to which target metaclass, and each binding within a rule declares which source structural feature (or derived expression) is assigned to a target structural feature.
Authoring these correspondences requires deep knowledge of both metamodels and is a labour-intensive, error-prone task. A natural question is whether LLMs can assist engineers in proposing these correspondences automatically, given only the metamodel descriptions and a transformation name. To answer this question empirically, we need a principled evaluation methodology that: (i) defines a ground truth from existing, authoritative ATL transformations; (ii) represents LLM outputs in a comparable interchange format; and (iii) quantifies agreement between the two at multiple semantic levels.
This tool operationalises that methodology.
The framework consists of three components.
The ground truth is derived automatically from an existing .atl file. The ATLTransformationParser parses the ATL source into an EMF model using the Eclipse ATL Common library. The MatchingExtractor then traverses the model and produces a structured JSON document — the interchange format — that encodes:
- the set of distinct class-pair matches (source metaclass → target metaclass), grouped across all rules that share the same pair;
- for each class pair, the set of structural feature matches, each linking a target feature to the set of source-side paths that contribute to it.
The extraction logic resolves helper-based bindings: when a binding expression invokes a context helper (e.g., m.fullName()), the extractor traverses the helper body and collects all self.<feature> accesses, exposing the underlying source-side structural dependencies transparently. This is essential because an LLM responding to a metamodel description will reason in terms of structural features, not helper call chains.
LLM-generated suggestions are represented as JSON files in a suggested-mappings format produced by the jJodel model editor. Each file declares a flat array of mappings, where each entry specifies:
kind:"class"or"attribute";source.class,source.feature: source-side endpoint;target.class,target.feature: target-side endpoint;confidence:"high","medium", or"low"— an LLM self-assessed confidence label;provider: the LLM provider, such as"GPT","Claude", or"Mistral".
Each mapping file represents one independent run of the LLM prompt, enabling repeated-sampling analysis.
The evaluation includes both LLM suggestions and an EMFCompare-based structural baseline:
JJodelBindingComparatoraligns the ground-truth interchange document with an LLM-generated suggestion file and produces a detailed diff.EMFCompareBaselineExtractorderives a baseline mapping from source and target Ecore metamodels using EMFCompare.ATLBaselineComparatorcompares that EMFCompare baseline against the ATL ground truth.ATLJJodelDiffexposes two-way ATL-vs-LLM comparison and three-way ATL-vs-EMFCompare-vs-LLM comparison from the command line.ValidationPerformanceAnalyzeriterates over a validation directory tree, derives a ground truth from each.atlfile found, compares it against every co-located suggestion file, and aggregates metrics per provider.
The current validation tree contains eight ATL transformations, and the RQ1 analysis combines repeated LLM runs with one deterministic EMFCompare baseline run per transformation.
Comparison proceeds in two stages: class-level matching followed by feature-level matching within each matched class pair.
A class pair (S, T) is considered a true positive (TP) at the class level if the LLM suggestion contains a class mapping from S to T and the ATL ground truth also contains a rule covering that pair. A pair present only in the ATL ground truth is a false negative (FN); a pair present only in the LLM output is a false positive (FP).
For each class pair (S, T) present in both the ATL ground truth and the LLM output, the comparator aligns feature bindings by target feature name. For each matched feature binding, the source-side dependency is classified into one of four categories:
| Category | Condition |
|---|---|
| exact | The LLM-proposed source feature equals the unique ATL source dependency |
| partial | The LLM-proposed source feature matches one of several ATL source dependencies |
| target-only | The ATL binding has no extractable source dependency (e.g., constant or unresolvable expression) |
| divergent | The LLM-proposed source feature is not among the ATL source dependencies |
The partial category arises when a binding is mediated by an OCL helper that depends on multiple source features (e.g., a fullName() helper that reads familyFather, name, and familyMother). In this case the LLM can, at best, predict one of the contributing features. Penalising this as a full error would be unfair; treating it as a full match would overstate correctness. The framework therefore applies a configurable partial match weight
Let
The partial contribution is split: the fraction
Note that divergent bindings contribute to both FP and FN because they represent a wrong prediction (FP) for a target feature that the ATL transformation does define (FN). This double-counting is intentional: a divergent binding is simultaneously a spurious claim and a missed correct claim.
Standard information-retrieval metrics are applied uniformly to class and binding counts:
The accuracy formula used here is the Jaccard similarity coefficient (also called Intersection over Union). It is chosen instead of the classical
An overall score is computed by pooling class-level and binding-level counts:
and analogously for FP and FN. This provides a single aggregate indicator of end-to-end mapping quality.
For multi-transformation, multi-run comparisons the framework reports both:
- Micro-aggregated metrics: TP, FP, FN are summed across all runs before computing precision/recall/accuracy. This weights each individual binding or class pair equally regardless of transformation size.
- Macro-averaged metrics: precision, recall, and accuracy are computed independently for each run, then averaged. This weights each run equally and is more sensitive to performance on small transformations.
The validation dataset currently comprises eight ATL transformations. Each validation subdirectory contains one ATL ground-truth transformation, the source and target Ecore metamodels, and multiple jJodel suggested-mapping JSON files.
| Transformation | Source Metamodel | Target Metamodel |
|---|---|---|
book2publication |
Book | Publication |
Class2Relational |
UML Class | Relational |
Grafcet2Petrinet |
IEC 61131 Grafcet | Petri Net |
Java2Table |
Java source | Database table |
mysql2km3 |
MySQL | KM3 |
spreedsheet2XML |
SpreadsheetML simplified | XML |
table2spreadsheet |
Database table | SpreadsheetML simplified |
xml2ant |
XML | Apache Ant |
The latest RQ1 analysis compares three LLM providers, GPT, Claude, and Mistral, against an EMFCompare structural baseline. The LLM providers are evaluated over repeated prompt runs, while EMFCompare is deterministic. The partial match weight is set to
The table below reports the ALL rows from results/rq1_aggregate.csv, using micro-aggregated overall metrics across the eight transformations.
| Provider | Precision | Recall | F1 | Accuracy |
|---|---|---|---|---|
| Claude | 0.680 | 0.725 | 0.701 | 0.540 |
| GPT | 0.625 | 0.286 | 0.392 | 0.244 |
| Mistral | 0.573 | 0.485 | 0.525 | 0.356 |
| EMFCompare | 0.571 | 0.053 | 0.096 | 0.051 |
Interpretation. Claude has the strongest overall balance in the current benchmark. GPT remains comparatively precise but misses many ATL-defined correspondences, while Mistral improves recall relative to GPT at the cost of lower precision. EMFCompare is included as a deterministic structural baseline; its low recall reflects that metamodel similarity alone does not recover most transformation-specific ATL bindings.
The older validation-performance.json file contains a previous four-transformation GPT/Claude-only report. Use the CSV files under results/ for the current RQ1 analysis.
- Java 11 or newer.
- Maven.
- Eclipse ATL/EMF/EMFCompare dependencies installed in the local Eclipse p2 pool at
~/.p2/pool/plugins, matching the system-scoped JAR names declared in pom.xml.
Build the standalone JAR with:
mvn package -Dexec.mainClass=org.atlbinding.ATLBindingAnalyzerThe shaded artifact is written to:
target/atl-binding-analyzer-1.0-SNAPSHOT-standalone.jar
java -jar target/atl-binding-analyzer-1.0-SNAPSHOT-standalone.jar \
path/to/transformation.atl [output.json]Suggested mappings are generated in the jJodel beta UI at https://beta.jjodel.io. The validation JSON files in this repository are exported directly from the Suggested Mappings panel.
For each transformation:
- Create or open a jJodel project for the transformation, for example
Grafcet2PetriNet. - Import or define both metamodels in the same megamodel. The screenshots show the source
Grafcetmetamodel and targetPetriNetmetamodel open as separate tabs. - Open a transformation tab and select the source and target metamodels from the toolbar, for example
SOURCE: GrafcetandTARGET: PetriNet. - In the Suggested Mappings panel, choose the model/provider to evaluate, for example
Mistral Large. - Click Analyze Metamodels. jJodel lists pending class and attribute mappings with confidence labels (
high,med,low) and may mark inherited feature mappings as auto-resolved. - For inspection in the UI, select mappings to move them from
pendingtoto insert; this draws colored links between source and target features. The repository validation files are exported suggestions, so inserting them into the transformation editor is not required for evaluation. - Click Export JSON and save the file in the corresponding validation directory, for example:
src/test/resources/validation/Grafcet2Petrinet/Grafcet_to_PetriNet_suggested_mappings (N).json
The exported JSON must keep the jJodel suggested-mappings shape:
{
"jjodel": {
"exportType": "suggested-mappings",
"schemaVersion": 1
},
"transformation": {
"name": "Grafcet_to_PetriNet",
"source": "Grafcet",
"target": "PetriNet"
},
"analysis": {
"provider": "Mistral",
"model": "mistral-large-latest",
"modelLabel": "Mistral Large"
},
"mappings": []
}Repeat the workflow for each provider/run. The analyzer groups results by analysis.provider, so keep that field consistent across exported files.
The jJodel AI matcher uses the following system prompt template to generate suggested mappings. The placeholders {{sourceName}}, {{sourceMetamodel}}, {{targetName}}, and {{targetMetamodel}} are filled at runtime with the selected metamodel names and their JSON representations.
You are an expert in model-driven engineering and metamodel transformations.
You generate mappings for JjTL (Jjodel Transformation Language).
Analyze these two metamodels and suggest semantic mappings between them.
## Source Metamodel: {{sourceName}}
{{sourceMetamodel}}
## Target Metamodel: {{targetName}}
{{targetMetamodel}}
## Task
Identify which elements from the Source metamodel should map to which elements in the Target metamodel.
Consider:
1. Semantic similarity (even if names are different)
2. Structural similarity
3. Type compatibility
4. Common modeling patterns
## JjTL Syntax Rules (MUST follow)
conversionHint values MUST be valid JjEL expressions following these rules:
- Equality uses '==' (NOT '===' or '=')
- Inequality uses '!='
- Conditionals: if x == 1 then "a" else "b" (NOT ternary '?:')
- Boolean operators: and, or, not, implies
- Null-safe navigation: parent?.name
- Null coalesce: parent?.name ?? "default"
- Value mappings: true=1, false=0
- Comments use '--' (NOT '#' or '//')
DO NOT use in conversionHint:
- Ternary '?:' -- use if/then/else instead
- Triple equals '===' -- use == instead
- Hash '#' or '//' for comments -- use -- instead
- JavaScript/TypeScript syntax
## Metamodel Rules
- NEVER use abstract classes as target classes -- abstract classes cannot be instantiated
- If the target metamodel has an abstract class with concrete subclasses, create SEPARATE mappings for each concrete subclass
- When mapping to different concrete subclasses, provide a "guardHint" explaining the distinguishing condition
## Response Format
Respond ONLY with a JSON array of mapping suggestions. No explanation, no markdown code blocks, just the raw JSON array:
[
{
"sourceClass": "ClassName",
"sourceAttribute": null,
"targetClass": "ConcreteClassName",
"targetAttribute": null,
"confidence": "high",
"reason": "Explanation",
"guardHint": "optional: condition for choosing this target subclass"
},
{
"sourceClass": "ClassName",
"sourceAttribute": "attrName",
"targetClass": "ConcreteClassName",
"targetAttribute": "attrName",
"confidence": "medium",
"reason": "Explanation",
"conversionHint": "sourceAttr.toUpper()"
}
]
Notes:
- sourceAttribute/targetAttribute should be null for class-level mappings
- confidence should be "high", "medium", or "low"
- Only suggest mappings you are confident about
- Quality over quantity
- conversionHint MUST be a valid JjEL expression (e.g., "name.toUpper()", "value.toString()", "true=1, false=0") or omitted entirely. NEVER put human-readable text or notes in conversionHint -- use the "reason" field for explanations instead. If no conversion is needed, omit conversionHint.
- guardHint is optional -- use it when the same source class maps to different target subclasses to explain the distinguishing condition
## Do Not Map Abstract Classes
Do not generate mapping entries where sourceClass is abstract. Instead, fold the attribute
bindings inherited from abstract superclasses into the mapping rules for the concrete subclasses
that inherit from them.
Example: if State and Transition both inherit `name` from abstract NamedElement, do not
generate a `NamedElement -> X` rule. Instead include `name := name` directly in the
`State -> Place` and `Transition -> Transition` rules.
## Target Attribute Must Exist
Do not generate attribute mapping entries where the target class has no matching attribute.
An entry with `targetAttribute: null` (or any name that does not exist on the target class)
is invalid -- omit the entry entirely rather than mapping to the class itself or inventing
a placeholder. This is a grammar violation of JjTL, not a style preference: emitting an
attribute mapping without a valid target attribute produces a binding with an empty left-hand
side (` := name`), which is unparseable.
Example: if State has attribute `name` and the target class Place has only `tokens`, do
NOT emit `{ sourceClass: "State", sourceAttribute: "name", targetClass: "Place",
targetAttribute: null }`. The correct action is to skip it -- Jjodie generates transformations,
it does not modify the target metamodel.
## Two-Pass Bindings for Cross-Type References
When a feature in the target metaclass is a REFERENCE (not an attribute) whose type is a metaclass
that is itself the TARGET of another mapping rule in the same transformation, that binding requires
two-pass resolution. In the JSON response, set conversionHint to the string:
"resolve(<sourceFeature>, <TargetType>)"
where <TargetType> is the target metaclass name.
Example: if Transition.nextState has type State and State maps to Place in this transformation, set:
conversionHint: "resolve(nextState, Place)"
## Container / Parent Bindings
When a feature in the target metaclass is a reference of type T, and the source metaclass is contained
(via a containment reference) in another metaclass that maps to T in the same transformation, generate
a SEPARATE mapping entry with:
sourceAttribute: "parent"
conversionHint: null
reason: "source container maps to <T> via <SourceContainer>-><T> rule"
Example: Transition is owned by State (State.ownedTransitions is a containment), State maps to Place,
and Transition.inputPlace has type Place -> generate an entry with sourceAttribute "parent".
## Unresolvable References
If a reference in the target has no clear mapping (not direct, not two-pass, not parent), include it in
the JSON response with confidence "low" and a reason explaining what is missing.
First extract the ATL ground truth to JSON, then compare it with a jJodel suggested-mappings JSON file:
java -cp target/atl-binding-analyzer-1.0-SNAPSHOT-standalone.jar \
org.atlbinding.ATLJJodelDiff \
--atl ground-truth.json \
--llm suggested-mappings.json \
--output diff.json \
--partial-match-weight 0.5The comparator also supports a three-way mode that compares ATL ground truth, an EMFCompare baseline, and an LLM prediction in one report:
java -cp target/atl-binding-analyzer-1.0-SNAPSHOT-standalone.jar \
org.atlbinding.ATLJJodelDiff \
--atl ground-truth.json \
--baseline emfcompare-baseline.json \
--llm suggested-mappings.json \
--output three-way-diff.jsonProgrammatic usage:
String atlJson = /* output of ATLBindingAnalyzer */;
String jjodelJson = /* content of a suggested-mappings JSON file */;
String diffJson = new JJodelBindingComparator(0.5).compare(atlJson, jjodelJson);java -cp target/atl-binding-analyzer-1.0-SNAPSHOT-standalone.jar \
org.atlbinding.ValidationPerformanceAnalyzer \
src/test/resources/validation \
validation-performance.json \
0.5 \
allArguments:
| Position | Description | Default |
|---|---|---|
| 1 | Path to validation root directory | src/test/resources/validation |
| 2 | Output JSON file path | stdout |
| 3 | Partial match weight |
0.5 |
| 4 | Confidence filter (all, high, medium, low, or comma-separated) |
all |
Each subdirectory under the validation root must contain exactly one .atl file (the ground truth) and any number of .json suggestion files (LLM outputs). The provider field inside each JSON file's analysis object determines how results are grouped.
The RQ1 script generates per-run and aggregate CSV files, including the EMFCompare baseline and attribute/reference splits:
python3 results/rq1_analysis.pyOutputs:
The ATL interchange format is specified in src/test/resources/INTERCHANGE_FORMAT.md. It is a class-first, feature-match-oriented JSON structure deliberately decoupled from ATL rule syntax, designed to be reproducible by any transformation language extractor. The semantic identity of a mapping is the tuple:
sourceClass → targetClass → targetFeature → sourcePaths
Rule names are treated as traceability metadata, not as identity keys.
src/main/java/org/atlbinding/
ATLBindingAnalyzer.java — CLI: extract bindings from an ATL file
ATLTransformationParser.java — ATL file parser (Eclipse ATL Common)
MatchingExtractor.java — Semantic extraction of class and feature matches
MatchingPrinter.java — JSON serialisation of TransformationMatch
JJodelBindingComparator.java — Diff engine: ATL ground truth vs. LLM suggestion
ATLBaselineComparator.java — Diff engine: ATL ground truth vs. EMFCompare baseline
ATLJJodelDiff.java — CLI: two-way and three-way comparison reports
EMFCompareBaselineExtractor.java — Extract baseline mappings from EMFCompare
ValidationPerformanceAnalyzer.java — Batch evaluation across multiple transformations
model/ — Domain model (TransformationMatch, RuleMatch, …)
src/test/resources/validation/
book2publication/ — ATL file, Ecore files, LLM suggestion files
Class2Relational/ — ATL file, Ecore files, LLM suggestion files
Grafcet2Petrinet/ — ATL file, Ecore files, LLM suggestion files
Java2Table/ — ATL file, Ecore files, LLM suggestion files
mysql2km3/ — ATL file, Ecore files, LLM suggestion files
spreedsheet2XML/ — ATL file, Ecore files, LLM suggestion files
table2spreadsheet/ — ATL file, Ecore files, LLM suggestion files
xml2ant/ — ATL file, Ecore files, LLM suggestion files
results/
rq1_analysis.py — Reproduction script for RQ1 CSV results
rq1_per_run.csv — Per-run metrics
rq1_aggregate.csv — Aggregate metrics
validation-performance.json — Older four-transformation GPT/Claude report
validation_table.tex — LaTeX table of validation-set characteristics