Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Eclipse Projects
Eclipse ESCET (Supervisory Control Engineering Toolkit)
escet
Commits
04755f71
Commit
04755f71
authored
Mar 25, 2022
by
Dennis Hendriks
Browse files
Merge branch 'develop' into 'master'
#264
master to develop for v0.5-RC1 See merge request
!287
parents
dcc21995
8239cb07
Pipeline
#2706
passed with stage
in 0 seconds
Changes
339
Pipelines
2
Expand all
Hide whitespace changes
Inline
Side-by-side
.mvn/extensions.xml
View file @
04755f71
...
...
@@ -11,8 +11,8 @@
-->
<extensions>
<extension>
<groupId>
org.eclipse.tycho
.extras
</groupId>
<artifactId>
tycho-
pomless
</artifactId>
<version>
2.
5
.0
</version>
<groupId>
org.eclipse.tycho
</groupId>
<artifactId>
tycho-
build
</artifactId>
<version>
2.
7
.0
</version>
</extension>
</extensions>
DEPENDENCIES.txt
View file @
04755f71
This diff is collapsed.
Click to expand it.
chi/org.eclipse.escet.chi.documentation/asciidoc/release-notes.asciidoc
View file @
04755f71
...
...
@@ -30,6 +30,7 @@ TBD
Improvements and fixes:
* Some small changes to the documentation (issue #271).
* The release notes for each version now contain the release date, with the exception of milestone releases and release candidates (issue #314).
=== Version 0.4 (2021-12-17)
...
...
chi/org.eclipse.escet.chi.documentation/asciidoc/tutorial/input-output.asciidoc
View file @
04755f71
...
...
@@ -197,13 +197,15 @@ An example:
int i = 5;
real r = 3.14;
write("%4d/%8.2f", i, r)
write("Result:\n");
write("%4d/%8.2f", i, r);
----
This fragment has the effect that the values of `i` and `r` are written to the screen as follows:
[source, console]
----
Result:
5/ 3.14
----
...
...
@@ -277,13 +279,16 @@ An example is:
----
int i = 5, j = 10;
real r = 3.14;
write("%6d\t%d\n\t%.2f\n", i, j, r)
write("Result:\n");
write("%6d\t%d\n\t%.2f\n", i, j, r);
----
The result looks like:
[source, console]
----
Result:
5 10
3.14
----
...
...
cif/org.eclipse.escet.cif.cif2cif.app/src/org/eclipse/escet/cif/cif2cif/app/CifToCifTransOption.java
View file @
04755f71
...
...
@@ -23,7 +23,10 @@ import java.util.List;
import
java.util.Map
;
import
org.eclipse.escet.cif.cif2cif.AddDefaultInitialValues
;
import
org.eclipse.escet.cif.cif2cif.AnonymizeNames
;
import
org.eclipse.escet.cif.cif2cif.CifToCifTransformation
;
import
org.eclipse.escet.cif.cif2cif.ConvertEventsControllability.ConvertCntrlEventsToUncntrl
;
import
org.eclipse.escet.cif.cif2cif.ConvertEventsControllability.ConvertUncntrlEventsToCntrl
;
import
org.eclipse.escet.cif.cif2cif.ElimAlgVariables
;
import
org.eclipse.escet.cif.cif2cif.ElimAutCasts
;
import
org.eclipse.escet.cif.cif2cif.ElimComponentDefInst
;
...
...
@@ -50,6 +53,7 @@ import org.eclipse.escet.cif.cif2cif.RemoveIoDecls;
import
org.eclipse.escet.cif.cif2cif.RemovePositionInfo
;
import
org.eclipse.escet.cif.cif2cif.RemovePrintDecls
;
import
org.eclipse.escet.cif.cif2cif.RemoveRequirements
;
import
org.eclipse.escet.cif.cif2cif.RemoveUnusedAlgVariables
;
import
org.eclipse.escet.cif.cif2cif.SimplifyOthers
;
import
org.eclipse.escet.cif.cif2cif.SimplifyValues
;
import
org.eclipse.escet.cif.cif2cif.SimplifyValuesNoRefs
;
...
...
@@ -94,6 +98,9 @@ public class CifToCifTransOption extends Option<String> {
TRANSFORMATIONS
=
map
();
TRANSFORMATIONS
.
put
(
"add-default-init-values"
,
AddDefaultInitialValues
.
class
);
TRANSFORMATIONS
.
put
(
"anonymize-names"
,
AnonymizeNames
.
class
);
TRANSFORMATIONS
.
put
(
"convert-uncntrl-events-to-cntrl"
,
ConvertUncntrlEventsToCntrl
.
class
);
TRANSFORMATIONS
.
put
(
"convert-cntrl-events-to-uncntrl"
,
ConvertCntrlEventsToUncntrl
.
class
);
TRANSFORMATIONS
.
put
(
"elim-alg-vars"
,
ElimAlgVariables
.
class
);
TRANSFORMATIONS
.
put
(
"elim-aut-casts"
,
ElimAutCasts
.
class
);
TRANSFORMATIONS
.
put
(
"elim-comp-def-inst"
,
ElimComponentDefInst
.
class
);
...
...
@@ -121,6 +128,7 @@ public class CifToCifTransOption extends Option<String> {
TRANSFORMATIONS
.
put
(
"remove-print-decls"
,
RemovePrintDecls
.
class
);
TRANSFORMATIONS
.
put
(
"remove-pos-info"
,
RemovePositionInfo
.
class
);
TRANSFORMATIONS
.
put
(
"remove-reqs"
,
RemoveRequirements
.
class
);
TRANSFORMATIONS
.
put
(
"remove-unused-alg-vars"
,
RemoveUnusedAlgVariables
.
class
);
TRANSFORMATIONS
.
put
(
"simplify-others"
,
SimplifyOthers
.
class
);
TRANSFORMATIONS
.
put
(
"simplify-values"
,
SimplifyValues
.
class
);
TRANSFORMATIONS
.
put
(
"simplify-values-optimized"
,
SimplifyValuesOptimized
.
class
);
...
...
cif/org.eclipse.escet.cif.cif2cif/src/org/eclipse/escet/cif/cif2cif/AnonymizeNames.java
0 → 100644
View file @
04755f71
//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2022 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
//
// This program and the accompanying materials are made available
// under the terms of the MIT License which is available at
// https://opensource.org/licenses/MIT
//
// SPDX-License-Identifier: MIT
//////////////////////////////////////////////////////////////////////////////
package
org.eclipse.escet.cif.cif2cif
;
import
static
org
.
eclipse
.
escet
.
common
.
java
.
Lists
.
list
;
import
static
org
.
eclipse
.
escet
.
common
.
java
.
Maps
.
map
;
import
java.util.List
;
import
java.util.Map
;
import
org.eclipse.escet.cif.common.CifCollectUtils
;
import
org.eclipse.escet.cif.common.CifEnumUtils
;
import
org.eclipse.escet.cif.common.CifTypeUtils
;
import
org.eclipse.escet.cif.metamodel.cif.AlgParameter
;
import
org.eclipse.escet.cif.metamodel.cif.ComponentDef
;
import
org.eclipse.escet.cif.metamodel.cif.ComponentInst
;
import
org.eclipse.escet.cif.metamodel.cif.ComponentParameter
;
import
org.eclipse.escet.cif.metamodel.cif.EventParameter
;
import
org.eclipse.escet.cif.metamodel.cif.Group
;
import
org.eclipse.escet.cif.metamodel.cif.LocationParameter
;
import
org.eclipse.escet.cif.metamodel.cif.Specification
;
import
org.eclipse.escet.cif.metamodel.cif.automata.Automaton
;
import
org.eclipse.escet.cif.metamodel.cif.automata.Location
;
import
org.eclipse.escet.cif.metamodel.cif.declarations.AlgVariable
;
import
org.eclipse.escet.cif.metamodel.cif.declarations.Constant
;
import
org.eclipse.escet.cif.metamodel.cif.declarations.ContVariable
;
import
org.eclipse.escet.cif.metamodel.cif.declarations.DiscVariable
;
import
org.eclipse.escet.cif.metamodel.cif.declarations.EnumDecl
;
import
org.eclipse.escet.cif.metamodel.cif.declarations.EnumLiteral
;
import
org.eclipse.escet.cif.metamodel.cif.declarations.Event
;
import
org.eclipse.escet.cif.metamodel.cif.declarations.InputVariable
;
import
org.eclipse.escet.cif.metamodel.cif.declarations.TypeDecl
;
import
org.eclipse.escet.cif.metamodel.cif.expressions.CastExpression
;
import
org.eclipse.escet.cif.metamodel.cif.functions.Function
;
import
org.eclipse.escet.cif.metamodel.cif.functions.FunctionParameter
;
import
org.eclipse.escet.cif.metamodel.cif.types.CifType
;
import
org.eclipse.escet.cif.metamodel.cif.types.Field
;
import
org.eclipse.escet.cif.metamodel.cif.types.StringType
;
import
org.eclipse.escet.cif.metamodel.cif.types.TupleType
;
import
org.eclipse.escet.cif.metamodel.java.CifWalker
;
import
org.eclipse.escet.common.java.Assert
;
/**
* In-place transformation that anonymizes the names of all named objects.
*
* <p>
* Precondition: Specifications with automaton to string casts are not supported.
* </p>
*/
public
class
AnonymizeNames
extends
CifWalker
implements
CifToCifTransformation
{
/**
* Mapping from name prefixes to the next free number for that prefix. Mapping starts empty, and entries are added
* as needed.
*/
private
Map
<
String
,
Integer
>
nextFreeNumbers
;
/** Mapping from enumeration declarations to their representatives. */
private
Map
<
EnumDecl
,
EnumDecl
>
enumRepresentatives
;
/** Mapping of enumeration literals of representative enumerations to their new names. */
private
Map
<
EnumLiteral
,
String
>
enumLitRepresentativesNewNames
;
@Override
public
void
transform
(
Specification
spec
)
{
// Clear next free number administration.
nextFreeNumbers
=
map
();
// Get enumeration representatives.
List
<
EnumDecl
>
enumDecls
=
list
();
CifCollectUtils
.
collectEnumDecls
(
spec
,
enumDecls
);
enumRepresentatives
=
CifEnumUtils
.
getEnumDeclReprs
(
enumDecls
);
// Assign new names to enumeration literals of enumeration representatives.
enumLitRepresentativesNewNames
=
map
();
for
(
EnumDecl
enumDecl:
enumRepresentatives
.
values
())
{
for
(
EnumLiteral
lit:
enumDecl
.
getLiterals
())
{
enumLitRepresentativesNewNames
.
put
(
lit
,
getName
(
"lit"
));
}
}
// Perform the transformation by walking over the specification.
walkSpecification
(
spec
);
}
@Override
protected
void
preprocessCastExpression
(
CastExpression
castExpr
)
{
// Automaton to string casts are not supported, to prevent the resulting specification from becoming invalid.
// For instance, the renamed locations of the automaton could be compared to string literals.
CifType
childType
=
CifTypeUtils
.
normalizeType
(
castExpr
.
getChild
().
getType
());
CifType
resultType
=
CifTypeUtils
.
normalizeType
(
castExpr
.
getType
());
if
(
CifTypeUtils
.
hasComponentLikeType
(
childType
)
&&
resultType
instanceof
StringType
)
{
throw
new
CifToCifPreconditionException
(
"Anonymizing names for a CIF specification with automaton to "
+
"string casts is currently not supported."
);
}
}
/**
* Returns a new name for an object to anonymize.
*
* @param prefix The prefix for the name.
* @return The new name.
*/
private
String
getName
(
String
prefix
)
{
Integer
nextNr
=
nextFreeNumbers
.
get
(
prefix
);
if
(
nextNr
==
null
)
{
nextNr
=
1
;
}
nextFreeNumbers
.
put
(
prefix
,
nextNr
+
1
);
return
prefix
+
nextNr
;
}
@Override
protected
void
preprocessAutomaton
(
Automaton
automaton
)
{
if
(
automaton
.
eContainer
()
instanceof
ComponentDef
)
{
// Body of an automaton definition.
automaton
.
setName
(
getName
(
"autdef"
));
}
else
{
// Automaton.
automaton
.
setName
(
getName
(
"aut"
));
}
}
@Override
protected
void
preprocessGroup
(
Group
group
)
{
if
(
group
instanceof
Specification
)
{
// Specifications must have 'specification' as their name.
Assert
.
check
(
"specification"
.
equals
(
group
.
getName
()));
}
else
if
(
group
.
eContainer
()
instanceof
ComponentDef
)
{
// Body of a group definition.
group
.
setName
(
getName
(
"grpdef"
));
}
else
{
// Group.
group
.
setName
(
getName
(
"grp"
));
}
}
@Override
protected
void
preprocessComponentInst
(
ComponentInst
componentInst
)
{
componentInst
.
setName
(
getName
(
"inst"
));
}
@Override
protected
void
preprocessAlgVariable
(
AlgVariable
algVar
)
{
if
(
algVar
.
eContainer
()
instanceof
AlgParameter
)
{
// Algebraic parameter.
algVar
.
setName
(
getName
(
"aparam"
));
}
else
{
// Algebraic variable.
algVar
.
setName
(
getName
(
"alg"
));
}
}
@Override
protected
void
preprocessConstant
(
Constant
constant
)
{
constant
.
setName
(
getName
(
"const"
));
}
@Override
protected
void
preprocessContVariable
(
ContVariable
contVar
)
{
contVar
.
setName
(
getName
(
"cont"
));
}
@Override
protected
void
preprocessDiscVariable
(
DiscVariable
discVar
)
{
if
(
discVar
.
eContainer
()
instanceof
FunctionParameter
)
{
// Function parameter.
discVar
.
setName
(
getName
(
"fparam"
));
}
else
{
// Discrete variable.
discVar
.
setName
(
getName
(
"disc"
));
}
}
@Override
protected
void
preprocessEnumDecl
(
EnumDecl
enumDecl
)
{
enumDecl
.
setName
(
getName
(
"enum"
));
}
@Override
protected
void
preprocessEvent
(
Event
event
)
{
// Give name based on being a parameter or an event.
if
(
event
.
eContainer
()
instanceof
EventParameter
)
{
// Event parameter.
event
.
setName
(
getName
(
"eparam"
));
}
else
{
// Event.
event
.
setName
(
getName
(
"evt"
));
}
// Prefix event name based on its supervisory kind. Don't prefix events without a supervisory kind, to prevent
// introducing such prefixes for specifications without (un)controllable events.
if
(
event
.
getControllable
()
!=
null
)
{
String
prefix
=
event
.
getControllable
()
?
"c_"
:
"u_"
;
event
.
setName
(
prefix
+
event
.
getName
());
}
}
@Override
protected
void
preprocessFunction
(
Function
function
)
{
function
.
setName
(
getName
(
"func"
));
}
@Override
protected
void
preprocessInputVariable
(
InputVariable
inputVar
)
{
inputVar
.
setName
(
getName
(
"input"
));
}
@Override
protected
void
preprocessTypeDecl
(
TypeDecl
typeDecl
)
{
typeDecl
.
setName
(
getName
(
"type"
));
}
@Override
protected
void
preprocessLocation
(
Location
location
)
{
if
(
location
.
eContainer
()
instanceof
LocationParameter
)
{
// Location parameter.
Assert
.
notNull
(
location
.
getName
());
location
.
setName
(
getName
(
"lparam"
));
}
else
{
// Location.
if
(
location
.
getName
()
!=
null
)
{
location
.
setName
(
getName
(
"loc"
));
}
}
}
@Override
protected
void
preprocessComponentParameter
(
ComponentParameter
compParam
)
{
compParam
.
setName
(
getName
(
"cparam"
));
}
@Override
protected
void
preprocessEnumLiteral
(
EnumLiteral
enumLit
)
{
// Compatible enumerations will need to remain compatible.
// We use the new names obtained previously for the literals of enumeration representatives.
// Get enumeration representative.
EnumDecl
enumDecl
=
(
EnumDecl
)
enumLit
.
eContainer
();
EnumDecl
enumRepresentative
=
enumRepresentatives
.
get
(
enumDecl
);
// Get literal representative.
int
index
=
enumDecl
.
getLiterals
().
indexOf
(
enumLit
);
EnumLiteral
litRepresentative
=
enumRepresentative
.
getLiterals
().
get
(
index
);
// Assign new name.
enumLit
.
setName
(
enumLitRepresentativesNewNames
.
get
(
litRepresentative
));
}
@Override
protected
void
preprocessField
(
Field
field
)
{
// Tuple type compatibility is based on field types, not field names.
// But a tuple-typed variable and a projection on that variable with a field name, must use matching names.
// Given that each tuple type has unique 'Field' class instances, we can't use global numbering.
// Hence, rather than global numbering, we number based on field indices.
if
(
field
.
getName
()
!=
null
)
{
TupleType
tupleType
=
(
TupleType
)
field
.
eContainer
();
int
index
=
tupleType
.
getFields
().
indexOf
(
field
);
field
.
setName
(
"field"
+
Integer
.
toString
(
index
+
1
));
}
}
}
cif/org.eclipse.escet.cif.cif2cif/src/org/eclipse/escet/cif/cif2cif/ConvertEventsControllability.java
0 → 100644
View file @
04755f71
//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2018, 2022 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
//
// This program and the accompanying materials are made available
// under the terms of the MIT License which is available at
// https://opensource.org/licenses/MIT
//
// SPDX-License-Identifier: MIT
//////////////////////////////////////////////////////////////////////////////
package
org.eclipse.escet.cif.cif2cif
;
import
static
java
.
util
.
Collections
.
emptySet
;
import
static
org
.
eclipse
.
escet
.
cif
.
common
.
CifCollectUtils
.
collectEvents
;
import
static
org
.
eclipse
.
escet
.
cif
.
common
.
CifScopeUtils
.
getScope
;
import
static
org
.
eclipse
.
escet
.
cif
.
common
.
CifScopeUtils
.
getSymbolNamesForScope
;
import
static
org
.
eclipse
.
escet
.
cif
.
common
.
CifScopeUtils
.
getUniqueName
;
import
static
org
.
eclipse
.
escet
.
cif
.
common
.
CifScopeUtils
.
hasCompDefInst
;
import
static
org
.
eclipse
.
escet
.
common
.
java
.
Lists
.
list
;
import
static
org
.
eclipse
.
escet
.
common
.
java
.
Strings
.
fmt
;
import
java.util.List
;
import
java.util.Set
;
import
org.eclipse.escet.cif.common.ScopeCache
;
import
org.eclipse.escet.cif.metamodel.cif.Specification
;
import
org.eclipse.escet.cif.metamodel.cif.declarations.Event
;
/**
* Basic class to convert events with a controllability status.
*
* <p>
* It also contains an inner class to convert all uncontrollable events to controllable events and an inner
* class to convert all controllable events to uncontrollable events.
* </p>
*
* <p>
* Precondition: Specifications with component definitions/instantiations are currently not supported.
* </p>
*/
public
final
class
ConvertEventsControllability
{
@SuppressWarnings
(
"javadoc"
)
private
ConvertEventsControllability
()
{
// Static class.
}
/**
* Converts events with a controllability status in the given specification to the desired controllability status.
*
* <p>
* Event names of modified events are changed if they use the specific prefix "c_" or "u_".
* </p>
*
* @param spec The specification to adapt.
* @param toControllable Set to {@code true} to convert uncontrollable events to controllable events or
* {@code false} to convert controllable events to uncontrollable events.
*/
public
static
void
convert
(
Specification
spec
,
boolean
toControllable
)
{
// Check no component definition/instantiation precondition.
if
(
hasCompDefInst
(
spec
))
{
String
eventSource
=
toControllable
?
"uncontrollable"
:
"controllable"
;
String
eventDestination
=
toControllable
?
"controllable"
:
"uncontrollable"
;
String
msg
=
fmt
(
"Converting %s events to %s events"
,
eventSource
,
eventDestination
);
throw
new
CifToCifPreconditionException
(
msg
+
" in a CIF specification with component definitions is currently not supported."
);
}
// Collect the events of the specification.
List
<
Event
>
events
=
list
();
collectEvents
(
spec
,
events
);
// Change the events.
String
prefixToReplace
=
toControllable
?
"u_"
:
"c_"
;
String
prefixReplacement
=
toControllable
?
"c_"
:
"u_"
;
ScopeCache
scopeCache
=
new
ScopeCache
();
for
(
Event
event:
events
)
{
if
(
event
.
getControllable
()
!=
null
&&
event
.
getControllable
()
!=
toControllable
)
{
event
.
setControllable
(
toControllable
);
// Change the name if necessary.
String
name
=
event
.
getName
();
Set
<
String
>
localNames
=
getSymbolNamesForScope
(
getScope
(
event
),
scopeCache
);
if
(
name
.
startsWith
(
prefixToReplace
))
{
String
newName
=
prefixReplacement
+
name
.
substring
(
prefixToReplace
.
length
());
// If the new name also exists, find a better name.
if
(
localNames
.
contains
(
newName
))
{
newName
=
getUniqueName
(
newName
,
localNames
,
emptySet
());
}
event
.
setName
(
newName
);
localNames
.
remove
(
name
);
localNames
.
add
(
newName
);
}
// Else name was not modified, no need to rename.
}
}
}
/**
* In-place transformation that converts all uncontrollable events to controllable events.
*
* <p>
* Precondition: Specifications with component definitions/instantiations are currently not supported.
* </p>
*/
public
static
class
ConvertUncntrlEventsToCntrl
implements
CifToCifTransformation
{
@Override
public
void
transform
(
Specification
spec
)
{
convert
(
spec
,
true
);
}
}
/**
* In-place transformation that converts all controllable events to uncontrollable events.
*
* <p>
* Precondition: Specifications with component definitions/instantiations are currently not supported.
* </p>
*/
public
static
class
ConvertCntrlEventsToUncntrl
implements
CifToCifTransformation
{
@Override
public
void
transform
(
Specification
spec
)
{
convert
(
spec
,
false
);
}
}
}
cif/org.eclipse.escet.cif.cif2cif/src/org/eclipse/escet/cif/cif2cif/RemoveUnusedAlgVariables.java
0 → 100644
View file @
04755f71
//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2020, 2022 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
//
// This program and the accompanying materials are made available
// under the terms of the MIT License which is available at
// https://opensource.org/licenses/MIT
//
// SPDX-License-Identifier: MIT
//////////////////////////////////////////////////////////////////////////////
package
org.eclipse.escet.cif.cif2cif
;
import
static
org
.
eclipse
.
escet
.
common
.
java
.
Lists
.
filter
;
import
static
org
.
eclipse
.
escet
.
common
.
java
.
Lists
.
list
;
import
static
org
.
eclipse
.
escet
.
common
.
java
.
Maps
.
map
;
import
static
org
.
eclipse
.
escet
.
common
.
java
.
Sets
.
difference
;
import
static
org
.
eclipse
.
escet
.
common
.
java
.
Sets
.
set
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.Set
;
import
org.eclipse.escet.cif.common.CifScopeUtils
;
import
org.eclipse.escet.cif.metamodel.cif.ComplexComponent
;
import
org.eclipse.escet.cif.metamodel.cif.Equation
;
import
org.eclipse.escet.cif.metamodel.cif.Specification
;
import
org.eclipse.escet.cif.metamodel.cif.declarations.AlgVariable
;
import
org.eclipse.escet.cif.metamodel.cif.expressions.AlgVariableExpression
;
import
org.eclipse.escet.cif.metamodel.java.CifWalker
;
import
org.eclipse.escet.common.emf.EMFHelper
;
/**
* In-place transformation that removes unused algebraic variables and their equations.
*
* <p>
* Precondition: Specifications with component definitions/instantiations are currently not supported.
* </p>
*/
public
class
RemoveUnusedAlgVariables
extends
CifWalker
implements
CifToCifTransformation
{
/** All algebraic variables encountered so far. */
private
Set
<
AlgVariable
>
allAlgVars
=
set
();
/** All algebraic variables used in expressions outside value expressions of other algebraic variables. */
private
Set
<
AlgVariable
>
allUsedAlgVars
=
set
();
/** Map of algebraic variables to the collection of algebraic variables used in its defining expressions. */
private
Map
<
AlgVariable
,
Set
<
AlgVariable
>>
algVarsReferredByAlgVar
=
map
();
/**
* If not {@code null}, the algebraic variable owning the value expression or equation that is currently being
* analyzed.
*/
private
AlgVariable
analyzingAlgVar
=
null
;
/** Equations defining values for algebraic variables. */
private
final
List
<
Equation
>
algEquations
=
list
();
@Override
public
void
transform
(
Specification
spec
)
{
// Check no component definition/instantiation precondition.
if
(
CifScopeUtils
.
hasCompDefInst
(
spec
))
{
String
msg
=
"Eliminating unused algebraic variables from a CIF specification with component "
+
"definitions is currently not supported."
;
throw
new
CifToCifPreconditionException
(
msg
);
}