blob: 964b6b4d9513b3c519330e3af9ed3b1b306d1972 [file] [log] [blame]
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.0.4, mkdocs-material-4.4.2">
<title>Model comparison (ECL) - Epsilon</title>
<link rel="stylesheet" href="../../assets/stylesheets/application.30686662.css">
<link rel="stylesheet" href="../../assets/stylesheets/application-palette.a8b3c06d.css">
<meta name="theme-color" content="">
<script src="../../assets/javascripts/modernizr.74668098.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono&display=fallback">
<style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../../assets/stylesheets/extra.css">
<link rel="stylesheet" href="../../assets/stylesheets/mermaid.css">
<link rel="stylesheet" href="../../assets/javascript/google-code-prettify/prettify.css">
<link rel="stylesheet" href="https://unpkg.com/mermaid@8.5.1/dist/mermaid.css">
<!-- FAVICON -->
<link rel="apple-touch-icon" sizes="76x76" href="/assets/images/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/images/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/images/favicon-16x16.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<link rel="shortcut icon" href="/assets/images/favicon.ico">
</head>
<body dir="ltr" data-md-color-primary="black" data-md-color-accent="orange">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="#the-epsilon-comparison-language-ecl" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="../.." title="Epsilon" class="md-header-nav__button md-logo">
<img src="../../assets/images/epsilon-white-background.png" width="24" height="24">
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
Epsilon
</span>
<span class="md-header-nav__topic">
Model comparison (ECL)
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
Git repository @ Eclipse
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main" role="main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="../.." title="Epsilon" class="md-nav__button md-logo">
<img src="../../assets/images/epsilon-white-background.png" width="48" height="48">
</a>
Epsilon
</label>
<div class="md-nav__source">
<a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
Git repository @ Eclipse
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." title="Home" class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../../download/" title="Download" class="md-nav__link">
Download
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-3" type="checkbox" id="nav-3" checked>
<label class="md-nav__link" for="nav-3">
Documentation
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-3">
Documentation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../" title="Overview" class="md-nav__link">
Overview
</a>
</li>
<li class="md-nav__item">
<a href="../emc/" title="Model connectivity" class="md-nav__link">
Model connectivity
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-3-3" type="checkbox" id="nav-3-3" checked>
<label class="md-nav__link" for="nav-3-3">
Languages
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="2">
<label class="md-nav__title" for="nav-3-3">
Languages
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../eol/" title="Object language (EOL)" class="md-nav__link">
Object language (EOL)
</a>
</li>
<li class="md-nav__item">
<a href="../egl/" title="Code generation (EGL)" class="md-nav__link">
Code generation (EGL)
</a>
</li>
<li class="md-nav__item">
<a href="../evl/" title="Model validation (EVL)" class="md-nav__link">
Model validation (EVL)
</a>
</li>
<li class="md-nav__item">
<a href="../etl/" title="Model transformation (ETL)" class="md-nav__link">
Model transformation (ETL)
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Model comparison (ECL)
</label>
<a href="./" title="Model comparison (ECL)" class="md-nav__link md-nav__link--active">
Model comparison (ECL)
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#abstract-syntax" class="md-nav__link">
Abstract Syntax
</a>
</li>
<li class="md-nav__item">
<a href="#concrete-syntax" class="md-nav__link">
Concrete Syntax
</a>
</li>
<li class="md-nav__item">
<a href="#execution-semantics" class="md-nav__link">
Execution Semantics
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#rule-and-block-overriding" class="md-nav__link">
Rule and Block Overriding
</a>
</li>
<li class="md-nav__item">
<a href="#comparison-outcome" class="md-nav__link">
Comparison Outcome
</a>
</li>
<li class="md-nav__item">
<a href="#rule-execution-scheduling" class="md-nav__link">
Rule Execution Scheduling
</a>
</li>
<li class="md-nav__item">
<a href="#the-matches-built-in-operation" class="md-nav__link">
The matches() built-in operation
</a>
</li>
<li class="md-nav__item">
<a href="#cyclic-invocation-of-matches" class="md-nav__link">
Cyclic invocation of matches()
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#fuzzy-and-dictionary-based-string-matching" class="md-nav__link">
Fuzzy and Dictionary-based String Matching
</a>
</li>
<li class="md-nav__item">
<a href="#the-match-trace" class="md-nav__link">
The Match Trace
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../eml/" title="Model merging (EML)" class="md-nav__link">
Model merging (EML)
</a>
</li>
<li class="md-nav__item">
<a href="../epl/" title="Pattern matching (EPL)" class="md-nav__link">
Pattern matching (EPL)
</a>
</li>
<li class="md-nav__item">
<a href="../flock/" title="Model Migration (Flock)" class="md-nav__link">
Model Migration (Flock)
</a>
</li>
<li class="md-nav__item">
<a href="../emg/" title="Model generation (EMG)" class="md-nav__link">
Model generation (EMG)
</a>
</li>
<li class="md-nav__item">
<a href="../eunit/" title="Unit testing (EUnit)" class="md-nav__link">
Unit testing (EUnit)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-3-4" type="checkbox" id="nav-3-4">
<label class="md-nav__link" for="nav-3-4">
Tools
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="2">
<label class="md-nav__title" for="nav-3-4">
Tools
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../picto/" title="Picto" class="md-nav__link">
Picto
</a>
</li>
<li class="md-nav__item">
<a href="../flexmi/" title="Flexmi" class="md-nav__link">
Flexmi
</a>
</li>
<li class="md-nav__item">
<a href="../eugenia/" title="Eugenia" class="md-nav__link">
Eugenia
</a>
</li>
<li class="md-nav__item">
<a href="../exeed/" title="Exeed" class="md-nav__link">
Exeed
</a>
</li>
<li class="md-nav__item">
<a href="../modelink/" title="Modelink" class="md-nav__link">
Modelink
</a>
</li>
<li class="md-nav__item">
<a href="../hutn/" title="HUTN" class="md-nav__link">
HUTN
</a>
</li>
<li class="md-nav__item">
<a href="../workflow/" title="Workflow (Ant tasks)" class="md-nav__link">
Workflow (Ant tasks)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../articles/" title="Articles" class="md-nav__link">
Articles
</a>
</li>
<li class="md-nav__item">
<a href="../../examples/" title="Examples" class="md-nav__link">
Examples
</a>
</li>
<li class="md-nav__item">
<a href="https://www.youtube.com/epsilondevs" title="Screencasts" class="md-nav__link">
Screencasts
</a>
</li>
<li class="md-nav__item">
<a href="https://www.youtube.com/playlist?list=PLRwHao6Ue0YUecg7vEUQTrtySIWwrd_mI" title="Lectures" class="md-nav__link">
Lectures
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-3-9" type="checkbox" id="nav-3-9">
<label class="md-nav__link" for="nav-3-9">
Javadoc
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="2">
<label class="md-nav__title" for="nav-3-9">
Javadoc
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="https://download.eclipse.org/epsilon/2.0/javadoc/" title="Stable" class="md-nav__link">
Stable
</a>
</li>
<li class="md-nav__item">
<a href="https://download.eclipse.org/epsilon/interim/javadoc/" title="Interim" class="md-nav__link">
Interim
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-4" type="checkbox" id="nav-4">
<label class="md-nav__link" for="nav-4">
Issues
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-4">
Issues
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/enter_bug.cgi?product=epsilon" title="Report a new issue" class="md-nav__link">
Report a new issue
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=blocker&bug_severity=critical&bug_severity=major&bug_severity=normal&bug_severity=minor&bug_severity=trivial" title="View open bugs" class="md-nav__link">
View open bugs
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=enhancement" title="View enhancement requests" class="md-nav__link">
View enhancement requests
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?bug_status=RESOLVED&list_id=17694438&product=epsilon&query_format=advanced" title="View issues resolved since the last stable release" class="md-nav__link">
View issues resolved since the last stable release
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time" title="View all issues" class="md-nav__link">
View all issues
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-5" type="checkbox" id="nav-5">
<label class="md-nav__link" for="nav-5">
Community
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-5">
Community
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-5-1" type="checkbox" id="nav-5-1">
<label class="md-nav__link" for="nav-5-1">
Who is using Epsilon?
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="2">
<label class="md-nav__title" for="nav-5-1">
Who is using Epsilon?
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../users/" title="Industry" class="md-nav__link">
Industry
</a>
</li>
<li class="md-nav__item">
<a href="../../users/education/" title="Education" class="md-nav__link">
Education
</a>
</li>
<li class="md-nav__item">
<a href="../../users/open-source/" title="Open-source projects" class="md-nav__link">
Open-source projects
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="https://projects.eclipse.org/projects/modeling.epsilon/who" title="Who is developing Epsilon?" class="md-nav__link">
Who is developing Epsilon?
</a>
</li>
<li class="md-nav__item">
<a href="https://www.eclipse.org/forums/index.php/f/22/" title="Forum" class="md-nav__link">
Forum
</a>
</li>
<li class="md-nav__item">
<a href="../../labs/" title="Epsilon Labs" class="md-nav__link">
Epsilon Labs
</a>
</li>
<li class="md-nav__item">
<a href="../../faq/" title="Frequently asked questions" class="md-nav__link">
Frequently asked questions
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../branding/" title="Branding" class="md-nav__link">
Branding
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#abstract-syntax" class="md-nav__link">
Abstract Syntax
</a>
</li>
<li class="md-nav__item">
<a href="#concrete-syntax" class="md-nav__link">
Concrete Syntax
</a>
</li>
<li class="md-nav__item">
<a href="#execution-semantics" class="md-nav__link">
Execution Semantics
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#rule-and-block-overriding" class="md-nav__link">
Rule and Block Overriding
</a>
</li>
<li class="md-nav__item">
<a href="#comparison-outcome" class="md-nav__link">
Comparison Outcome
</a>
</li>
<li class="md-nav__item">
<a href="#rule-execution-scheduling" class="md-nav__link">
Rule Execution Scheduling
</a>
</li>
<li class="md-nav__item">
<a href="#the-matches-built-in-operation" class="md-nav__link">
The matches() built-in operation
</a>
</li>
<li class="md-nav__item">
<a href="#cyclic-invocation-of-matches" class="md-nav__link">
Cyclic invocation of matches()
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#fuzzy-and-dictionary-based-string-matching" class="md-nav__link">
Fuzzy and Dictionary-based String Matching
</a>
</li>
<li class="md-nav__item">
<a href="#the-match-trace" class="md-nav__link">
The Match Trace
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1 id="the-epsilon-comparison-language-ecl">The Epsilon Comparison Language (ECL)<a class="headerlink" href="#the-epsilon-comparison-language-ecl" title="Permanent link">&para;</a></h1>
<p>Model comparison is the task of identifying <em>matching</em> elements between models. In general, <em>matching</em> elements are elements that are involved in a relationship of interest. For example, before merging homogeneous models, it is essential to identify overlapping (common) elements so that they do not appear in duplicate in the merged model. Similarly, in heterogeneous model merging, it is a prerequisite to identify the elements on which the two models will be merged. Finally, in transformation testing, matching elements are pairs consisting of elements in the input model and their generated counterparts in the output model.</p>
<p>The aim of the Epsilon Comparison Language (ECL) is to enable users to specify comparison algorithms in a rule-based manner to identify pairs of matching elements between two models of potentially different metamodels and modelling technologies. In this section, the abstract and concrete syntax, as well as the execution semantics of the language, are discussed in detail.</p>
<h2 id="abstract-syntax">Abstract Syntax<a class="headerlink" href="#abstract-syntax" title="Permanent link">&para;</a></h2>
<p>In ECL, comparison specifications are organized in modules (<em>EcLModule</em>). As illustrated below, <em>EclModule</em> (indirectly) extends <em>EolModule</em> which means that it can contain user-defined operations and import other library modules and ECL modules. Apart from operations, an ECL module contains a set of match-rules (<em>MatchRule</em>) and a set of <em>pre</em> and <em>post</em> blocks than run before and after all comparisons, respectively.</p>
<p><em>MatchRules</em> enable users to perform comparison of model elements at a high level of abstraction. Each match-rule declares a name, and two parameters (<em>leftParameter</em> and <em>rightParameter</em>) that specify the types of elements it can compare. It also optionally defines a number of rules it inherits (<em>extends</em>) and if it is <em>abstract</em>, <em>lazy</em> and/or <em>greedy</em>. The semantics of the latter are discussed shortly.</p>
<div class="mermaid mermaid-90">classDiagram
class MatchRule {
-name: String
-abstract: Boolean
-lazy: Boolean
-unique: Boolean
-greedy: Boolean
-guard: ExecutableBlock&lt;Boolean&gt;
-compare: ExecutableBlock&lt;Boolean&gt;
-do: ExecutableBlock&lt;Void&gt;
}
class Parameter {
-name: String
-type: EolType
}
class NamedStatementBlockRule {
-name: String
-body: StatementBlock
}
EolModule &lt;|-- ErlModule
EclModule --|&gt; ErlModule
Pre --|&gt; NamedStatementBlockRule
Post --|&gt; NamedStatementBlockRule
ErlModule -- Pre: pre *
ErlModule -- Post: post *
EclModule -- MatchRule: rules *
MatchRule -- Parameter: left
MatchRule -- Parameter: right
MatchRule -- MatchRule: extends *</div>
<p>A match rule has three parts. The <em>guard</em> part is an EOL expression or statement block that further limits the applicability of the rule to an even narrower range of elements than that specified by the <em>left</em> and <em>right</em> parameters. The <em>compare</em> part is an EOL expression or statement block that is responsible for comparing a pair of elements and deciding if they match or not. Finally, the <em>do</em> part is an EOL expression or block that is executed if the <em>compare</em> part returns true to perform any additional actions required.</p>
<p><em>Pre</em> and <em>post</em> blocks are named blocks of EOL statements which as discussed in the sequel are executed before and after the match-rules have been executed respectively.</p>
<h2 id="concrete-syntax">Concrete Syntax<a class="headerlink" href="#concrete-syntax" title="Permanent link">&para;</a></h2>
<p>The concrete syntax of a match-rule is displayed below.</p>
<div class="highlight"><pre><span></span><code>(@lazy)?
(@greedy)?
(@abstract)?
rule &lt;name&gt;
match &lt;leftParameterName&gt;:&lt;leftParameterType&gt;
with &lt;rightParameterName&gt;:&lt;rightParameterType&gt;
(extends &lt;ruleName&gt;(, &lt;ruleName&gt;)*)? {
(guard (:expression)|({statementBlock}))?
compare (:expression)|({statementBlock})
(do {statementBlock})?
}
</code></pre></div>
<p><em>Pre</em> and <em>post</em> blocks have a simple syntax that, as shown below, consists of the identifier (<em>pre</em> or <em>post</em>), an optional name and the set of statements to be executed enclosed in curly braces.</p>
<div class="highlight"><pre><span></span><code>(pre|post) &lt;name&gt; {
statement+
}
</code></pre></div>
<h2 id="execution-semantics">Execution Semantics<a class="headerlink" href="#execution-semantics" title="Permanent link">&para;</a></h2>
<h3 id="rule-and-block-overriding">Rule and Block Overriding<a class="headerlink" href="#rule-and-block-overriding" title="Permanent link">&para;</a></h3>
<p>An ECL module can import a number of other ECL modules. In such a case, the importing ECL module inherits all the rules and pre/post blocks specified in the modules it imports (recursively). If the module specifies a rule or a pre/post block with the same name, the local rule/block overrides the imported one respectively.</p>
<h3 id="comparison-outcome">Comparison Outcome<a class="headerlink" href="#comparison-outcome" title="Permanent link">&para;</a></h3>
<p>As illustrated below, the result of comparing two models with ECL is a trace (<em>MatchTrace</em>) that consists of a number of matches (<em>Match</em>). Each match holds a reference to the objects from the two models that have been compared (<em>left</em> and <em>right</em>), a boolean value that indicates if they have been found to be <em>matching</em> or not, a reference to the <em>rule</em> that has made the decision, and a Map (<em>info</em>) that is used to hold any additional information required by the user (accessible at runtime through the <em>matchInfo</em> implicit variable). During the matching process, a second, temporary, match trace is also used to detect and resolve cyclic invocation of match-rules as discussed in the sequel.</p>
<div class="mermaid mermaid-80">classDiagram
class Match {
-left: Object
-right: Object
-matching: Boolean
}
class EclContext {
-matchTrace: MatchTrace
-tempMatchTrace: MatchTrace
}
MatchRule -- Match: rule
MatchTrace -- Match: matches *
EclContext --|&gt; EolContext
EclContext -- MatchTrace
Map -- Match: info</div>
<h3 id="rule-execution-scheduling">Rule Execution Scheduling<a class="headerlink" href="#rule-execution-scheduling" title="Permanent link">&para;</a></h3>
<p>Non-abstract, non-lazy match-rules are evaluated automatically by the execution engine in a top-down fashion - with respect to their order of appearance - in two passes. In the first pass, each rule is evaluated for all the pairs of instances in the two models that have a type-of relationship with the types specified by the <em>leftParameter</em> and <em>rightParameter</em> of the rule. In the second pass, each rule that is marked as <em>greedy</em> is executed for all pairs that have not been compared in the first pass, and which have a kind-of relationship with the types specified by the rule. In both passes, to evaluate the compare part of the rule, the guard must be satisfied.</p>
<p>Before the compare part of a rule is executed, the compare parts of all of the rules it extends (super-rules) must be executed (recursively). Before executing the compare part of a super-rule, the engine verifies that the super-rule is actually applicable to the elements under comparison by checking for type conformance and evaluating the guard part of the super-rule.</p>
<p>If the compare part of a rule evaluates to true, the optional do part is executed. In the do part the user can specify any actions that need to be performed for the identified matching elements, such as to populate the <em>info</em> map of the established <em>match</em> with additional information. Finally, a new match is added to the match trace that has its <em>matching</em> property set to the logical conjunction of the results of the evaluation of the compare parts of the rule and its super-rules.</p>
<h3 id="the-matches-built-in-operation">The <em>matches()</em> built-in operation<a class="headerlink" href="#the-matches-built-in-operation" title="Permanent link">&para;</a></h3>
<p>To refrain from performing duplicate comparisons and to de-couple match-rules from each other, ECL provides the built-in <em>matches(opposite : Any)</em> operation for model elements and collections. When the <em>matches()</em> operation is invoked on a pair of objects, it queries the main and temporary match-traces to discover if the two elements have already been matched and if so it returns the cached result of the comparison. Otherwise, it attempts to find an appropriate match rule to compare the two elements and if such a rule is found, it returns the result of the comparison, otherwise it returns false. Unlike the top-level execution scheme, the <em>matches()</em> operation invokes both <em>lazy</em> and <em>non-lazy</em> rules.</p>
<p>In addition to objects, the <em>matches</em> operations can also be invoked to match pairs of collections of the same type (e.g. a Sequence against a Sequence). When invoked on ordered collections (i.e. <em>Sequence</em> and <em>OrderedSet</em>), it examines if the collections have the same size and each item of the source collection matches with the item of the same index in the target collection. Finally, when invoked on unordered collections (i.e. <em>Bag</em> and <em>Set</em>), it examines if for each item in the source collection, there is a matching item in the target collection irrespective of its index. Users can also override the built-in <em>matches</em> operation using user-defined operations with the same name, that loosen or strengthen the built-in semantics.</p>
<h3 id="cyclic-invocation-of-matches">Cyclic invocation of <em>matches()</em><a class="headerlink" href="#cyclic-invocation-of-matches" title="Permanent link">&para;</a></h3>
<p>Providing the built-in <em>matches</em> operation significantly simplifies comparison specifications. It also enhances decoupling between match-rules from each other as when a rule needs to compare two elements that are outside its scope, it does not need to know/specify which other rule can compare those elements explicitly.</p>
<p>On the other hand, it is possible - and quite common indeed - for two rules to implicitly invoke each other. For example consider the match rule below that attempts to match nodes of the simple Tree metamodel.</p>
<div class="mermaid mermaid-40">classDiagram
class Tree {
+label: String
+parent: Tree
+children: Tree[*]
}
Tree -- Tree</div>
<pre class="prettyprint lang-ecl"><code>rule Tree2Tree
match l : T1!Tree
with r : T2!Tree {
compare : l.label = r.label and
l.parent.matches(r.parent) and
l.children.matches(r.children)
}</code></pre>
<p>The rule specifies that for two Tree nodes (<em>l</em> and <em>r</em>) to match, they should have the same label, belong to matching parents and have matching children. In the absence of a dedicated mechanism for cycle detection and resolution, the rule would end up in an infinite loop. To address this problem, ECL provides a temporary match-trace which is used to detect and resolve cyclic invocations of the <em>match()</em> built-in operation.</p>
<p>As discussed above, a match is added to the primary match-trace as soon as the compare part of the rule has been executed to completion. By contrast, a temporary match (with its <em>matching</em> property set to <em>true</em>) is added to the temporary trace before the compare part is executed. In this way, any subsequent attempts to match the two elements from invoked rules will not re-invoke the rule. Finally, when a top-level rule returns, the temporary match trace is reset.</p>
<h2 id="fuzzy-and-dictionary-based-string-matching">Fuzzy and Dictionary-based String Matching<a class="headerlink" href="#fuzzy-and-dictionary-based-string-matching" title="Permanent link">&para;</a></h2>
<p>In the example above, the rule specifies that to match, two trees must - among other criteria - have the same label. However, there are cases when a less-strict approach to matching string properties of model elements is desired. For instance, when comparing two UML models originating from different organizations, it is common to encounter ontologically equivalent classes which however have different names (e.g. Client and Customer). In this case, to achieve a more sound matching, the use of a dictionary or a lexical database (e.g. WordNet) is necessary. Alternatively, fuzzy string matching algorithms can be used.</p>
<p>As several such tools and algorithms have been implemented in various programming languages, it is a sensible approach to reuse them instead of re-implementing them. For example, in the listing below a wrapper for the Simmetrics fuzzy string comparison tool is used to compare the labels of the trees using the Levenshtein algorithm. To achieve this, line 11 invokes the <em>fuzzyMatch()</em> operation defined in lines 16-18 which uses the simmterics native tool (instantiated in lines 2-4) to match the two labels using their Levenshtein distance with a threshold of 0.5.</p>
<pre class="prettyprint lang-ecl"><code>pre {
var simmetrics =
new Native("org.epsilon.ecl.tools.
textcomparison.simmetrics.SimMetricsTool");
}
rule FuzzyTree2Tree
match l : T1!Tree
with r : T2!Tree {
compare : l.label.fuzzyMatch(r.label) and
l.parent.matches(r.parent) and
l.children.matches(r.children)
}
operation String fuzzyMatch(other : String) : Boolean {
return simmetrics.similarity(self,other,"Levenshtein") &gt; 0.5;
}</code></pre>
<h2 id="the-match-trace">The Match Trace<a class="headerlink" href="#the-match-trace" title="Permanent link">&para;</a></h2>
<p>Users can query and modify the match trace calculated during the comparison process in the post sections of the module or export it into another application or Epsilon program. For example, in a post section, the trace can be printed to the default output stream or serialized into a model of an arbitrary metamodel. In another use case, the trace may be exported to be used in the context of a validation module that will use the identified matches to evaluate inter-model constraints, or in a merging module that will use the matches to identify the elements on which the two models will be merged.</p>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../etl/" title="Model transformation (ETL)" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Model transformation (ETL)
</span>
</div>
</a>
<a href="../eml/" title="Model merging (EML)" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Model merging (EML)
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright © Eclipse Foundation, Inc. All Rights Reserved.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">Material for MkDocs</a>
</div>
<div class="md-footer-copyright epsilon-eclipse-links">
<ul>
<li><a href="https://www.eclipse.org/legal/privacy.php">Privacy Policy</a></li>
<li><a href="https://www.eclipse.org/legal/termsofuse.php">Terms of Use</a></li>
<li><a href="https://www.eclipse.org/legal/copyright.php">Copyright Agent</a></li>
</ul>
</div>
</div>
</div>
</footer>
</div>
<script src="../../assets/javascripts/application.c648116f.js"></script>
<script>app.initialize({version:"1.0.4",url:{base:"../.."}})</script>
<script src="https://unpkg.com/mermaid@8.5.1/dist/mermaid.min.js"></script>
<script src="../../assets/javascript/mermaid.js"></script>
<script src="../../assets/javascript/jquery.js"></script>
<script src="../../assets/javascript/google-code-prettify/prettify.js"></script>
<script src="../../assets/javascript/google-code-prettify/lang-emfatic.js"></script>
<script src="../../assets/javascript/google-code-prettify/lang-epsilon.js"></script>
<script src="../../assets/javascript/google-code-prettify/prettyprint.js"></script>
</body>
</html>