Skip to content
Snippets Groups Projects
Commit 710fca1a authored by René Schöne's avatar René Schöne
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 1001 additions and 0 deletions
# TTC 2018: Case 1 "Quality-based Software-Selection and Hardware-Mapping as Model Transformation Problem"
## Getting started
In order to get the case working, perform the following steps:
- clone the repository: `git clone git@git-st.inf.tu-dresden.de:stgroup/ttc18.git && cd ttc18`
- build it: `./gradlew build` (or `gradlew.bat build` on Windows)
- run the benchmark: `./gradlew benchmarkFull`
- as this might take long, running a single scenario is possible with `./gradlew benchmarkFull '-Pscenario=1'`
## Overview over the repository structure
All modules are prefixed with `jastadd-mquat`, as this is an implementation of MQuAT (Multi-Quality AutoTuning) based on [JastAdd](http://www.jastadd.org). There are 5 modules:
- `base`: Contains the specifications for grammar and attributes, (de-)serializers and the model generator
- `benchmark`: Benchmark infrastructure and settings
- `solver`: Interfaces for solvers, and a small testsuite
- `solver-ilp`: Reference implementation using ILP
- `solver-simple`: Naïve, brute-force solver written in Java
**TODO: Check links** https://git-st.inf.tu-dresden.de/stgroup/ttc18/blob/master/jastadd-mquat-benchmark/src/main/java/de/tudresden/inf/st/mquat/benchmark/BenchmarkableSolver.java
## Creating a solution
A new solution should be created using a new module (or multiple, if necessary). You can use the simple-solver module as an example.
The following steps need to be completed:
1. Create an implementation of [`de.tudresden.inf.st.mquat.solving.BenchmarkableSolver`](https://git-st.inf.tu-dresden.de/stgroup/ttc18/blob/master/jastadd-mquat-solver/src/main/java/de/tudresden/inf/st/mquat/solving/BenchmarkableSolver.java) (which extends the [`Solver`](https://git-st.inf.tu-dresden.de/stgroup/ttc18/blob/master/jastadd-mquat-solver/src/main/java/de/tudresden/inf/st/mquat/solving/Solver.java) interface). The main method here is `public Solution solve(Root model) throws SolvingException`, which takes a model as input an returns a solution
1. Add an include of your project to `settings.gradle`
1. Optional step: Create a test case by extending the [`HandwrittenTestSuite`](https://git-st.inf.tu-dresden.de/stgroup/ttc18/blob/master/jastadd-mquat-solver/src/test/java/de/tudresden/inf/st/mquat/solving/HandwrittenTestSuite.java)
1. Add a compile dependency to your project in `build.gradle` of the project `jastadd-mquat-benchmark`
1. Update [`de.tudresden.inf.st.mquat.benchmark.SolverFactory.createAvailableSolversIfNeeded`](https://git-st.inf.tu-dresden.de/stgroup/ttc18/blob/master/jastadd-mquat-benchmark/src/main/java/de/tudresden/inf/st/mquat/benchmark/SolverFactory.java#L22) to create a new instance of your solver
1. Add the name of your solver to the benchmark settings
- use `jastadd-mquat-benchmark/src/main/resources/scenarios.json` for the Gradle task `benchmarkFull`
- use `jastadd-mquat-benchmark/src/main/resources/local-benchmark-settings.json` for the Gralde task `benchmarkCustom` (see [Custom Benchmark](#custom-benchmark) for details)
1. Run the benchmark, either `./gradlew benchmarkFull` or `./gradlew benchmarkCustom`
## Custom Benchmark
To test your solution, the Gradle task `benchmarkCustom` can be used. This task generates a custom set of models and runs a benchmark for them.
All default parameters are specified in the file `benchmark-settings.json` within the directory `jastadd-mquat-benchmark/src/main/resources`.
To change them, create a new file in this directory named `local-benchmark-settings.json`.
In this local version, all parameter values override the default settings, but are ignored when committing.
To test your solver with the name `fancy-solver` along with the reference implementation using a model with `10` and `15` requests and a timeout of 50 seconds, the file `local-benchmark-settings.json` would be as follows.
```json
{
"solvers": [
"ilp-direct",
"fancy-solver"
],
"basic": {
"verbose": true,
"minRequests": 10,
"maxRequests": 15,
"stepRequests": 5,
"timeoutValue": 50,
"timeoutUnit": "SECONDS",
"total": 2
}
}
```
The value `total` is used to constrain the total number of models to be generated. Set this to `null` (the default) to generate all value for the defined parameter ranges.
Refer to [`de.tudresden.inf.st.mquat.generator.ScenarioDescription`](https://git-st.inf.tu-dresden.de/stgroup/ttc18/blob/master/jastadd-mquat-base/src/main/java/de/tudresden/inf/st/mquat/generator/ScenarioDescription.java) for a description of the possible parameters.
## Notes and Troubleshooting
- please use the gradle wrapper script, as different version of Gradle might not work with the setup
- the wrapper script uses version `3.3`
- if anything is not working as expected, feel free to contact on of the authors of the TTC case or open an [issue](https://git-st.inf.tu-dresden.de/stgroup/ttc18/issues/new)
{
"resolveProperty": {
"returntype": "Property",
"kind": "syn",
"args": "String name",
"eqs": [
"Component"
]
},
"isSoftwareDesignator": {
"returntype": "boolean",
"kind": "syn",
"args": "",
"eqs": [
"Designator"
]
},
"findPropertyByName": {
"returntype": "Property",
"kind": "syn",
"args": "String name",
"eqs": [
"SoftwareModel"
]
},
"asPropertyResourceDesignator": {
"returntype": "PropertyResourceDesignator",
"kind": "syn",
"args": "",
"eqs": [
"Designator"
]
},
"isMetaParameterDesignator": {
"returntype": "boolean",
"kind": "syn",
"args": "",
"eqs": [
"Designator"
]
},
"asSoftwareDesignator": {
"returntype": "SoftwareDesignator",
"kind": "syn",
"args": "",
"eqs": [
"Designator"
]
},
"isPropertyResourceDesignator": {
"returntype": "boolean",
"kind": "syn",
"args": "",
"eqs": [
"Designator"
]
},
"findImplementationByName": {
"returntype": "Implementation",
"kind": "syn",
"args": "String name",
"eqs": [
"Root"
]
},
"getRequiringClauseValue": {
"returntype": "double",
"kind": "syn",
"args": "ResourceType type, String propertyName, int index",
"eqs": [
"Implementation"
]
},
"findInstanceByName": {
"returntype": "Instance",
"kind": "syn",
"args": "String name",
"eqs": [
"ResourceRequirement"
]
},
"findResourceTypeByName": {
"returntype": "ResourceType",
"kind": "syn",
"args": "String name",
"eqs": [
"HardwareModel"
]
},
"findSubResourceByTypeName": {
"returntype": "Resource",
"kind": "syn",
"args": "String name",
"eqs": [
"Resource"
]
},
"resolveMetaParameter": {
"returntype": "MetaParameter",
"kind": "syn",
"args": "String name",
"eqs": [
"SoftwareModel"
]
},
"findResourceByName": {
"returntype": "Resource",
"kind": "syn",
"args": "String name",
"eqs": [
"Resource"
]
},
"getCurrentValueByProperty": {
"returntype": "double",
"kind": "syn",
"args": "Property property",
"eqs": [
"Resource"
]
},
"findSubResourceTypeByName": {
"returntype": "ResourceType",
"kind": "syn",
"args": "String name",
"eqs": [
"ResourceType"
]
},
"getRequiringClauseInstance": {
"returntype": "Instance",
"kind": "syn",
"args": "ResourceType type, String propertyName, int index",
"eqs": [
"Implementation"
]
},
"findFirstProvidingClause": {
"returntype": "Clause",
"kind": "syn",
"args": "Property property",
"eqs": [
"Implementation"
]
},
"findRequestByName": {
"returntype": "Request",
"kind": "syn",
"args": "String name",
"eqs": [
"Root"
]
},
"getCurrentValueByPropertyName": {
"returntype": "double",
"kind": "syn",
"args": "String name",
"eqs": [
"Resource"
]
},
"getConstraintValueByName": {
"returntype": "double",
"kind": "syn",
"args": "String name",
"eqs": [
"Request"
]
},
"resolveQualifiedName": {
"returntype": "Designator",
"kind": "syn",
"args": "QualifiedName qn",
"eqs": [
"Implementation"
]
},
"root": {
"returntype": "Root",
"kind": "syn",
"args": "",
"eqs": [
"ASTNode"
]
},
"asMetaParameterDesignator": {
"returntype": "MetaParameterDesignator",
"kind": "syn",
"args": "",
"eqs": [
"Designator"
]
}
}
\ No newline at end of file
allprojects {
group = 'de.tudresden.inf.st'
version = '1.0.0-SNAPSHOT'
}
subprojects {
apply plugin: 'java'
sourceCompatibility = 1.8
targetCompatibility = 1.8
task packageSources(type: Jar) {
classifier = 'sources'
from sourceSets.main.allSource
}
artifacts.archives packageSources
task longRunningTest(type: Test, description: 'Runs long running tests.', group: 'verification') {
outputs.upToDateWhen {false}
systemProperty "de.tudresden.inf.st.mquat.longRunningTest", "true"
}
configurations {
testArtifacts.extendsFrom testRuntime
}
task testJar(type: Jar) {
classifier "test"
from sourceSets.test.output
}
artifacts {
testArtifacts testJar
}
repositories {
maven { url "https://www.xypron.de/repository" }
}
}
#!/bin/bash
./gradlew checkSolution -PfileNames="$(realpath $1)","$(realpath $2)"
glpkPath = /usr/local/lib/jni
#Mon Jan 15 16:36:10 CET 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip
gradlew 0 → 100755
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save ( ) {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
out/
.gradle
src/gen
src/gen-res
build
coverage
/bin/
/build/
/out/
dynamic-values=0
NTA-computed=0
NTA-cached=1
NTA-depth=1
nodeThreshold=1000
showNodes=1
showEdges=1
niceEdges=1
normalEdgeWidth=1.0
refEdgeWidth=2.0
dashedEdgeWidth=0.2
normalVertexEdgeWidth=1.0
dashedVertexEdgeWidth=0.2
group 'de.tudresden.inf.st'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'jastadd'
apply plugin: 'application'
//mainClassName = 'de.tudresden.inf.st.mquat.Main'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.8.1'
compile group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0'
testCompile 'junit:junit:4.12'
testCompile files('libs/DrAST-1.2.2.jar')
testCompile fileTree(dir: "${System.properties['java.home']}", include: '**/jfxrt.jar')
}
run {
mainClassName = 'de.tudresden.inf.st.mquat.Main'
standardInput = System.in
if (project.hasProperty("appArgs")) {
args Eval.me(appArgs)
}
}
task toEcl(type: JavaExec, dependsOn: assemble) {
group "application"
classpath = sourceSets.test.runtimeClasspath
main = 'de.tudresden.inf.st.mquat.Main'
}
task checkSolution(type: JavaExec, dependsOn: assemble) {
group "application"
classpath = sourceSets.test.runtimeClasspath
main = 'de.tudresden.inf.st.mquat.MainCheck'
if (project.hasProperty("fileNames")) {
args(fileNames.split(','))
}
}
buildscript {
repositories.mavenLocal()
repositories.mavenCentral()
dependencies {
classpath 'org.jastadd:jastaddgradle:1.10.3'
}
}
jar {
manifest {
attributes(
'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
'Main-Class': 'de.tudresden.inf.st.mquat.Main'
)
}
}
javadoc {
// this is only run to get the index file etc.
failOnError = false
}
task DrAST(type: JavaExec, dependsOn:jar) {
group = "verification"
description = 'run the DrAST visual debugger tool'
classpath = sourceSets.test.runtimeClasspath
main = 'de.tudresden.inf.st.mquat.DrAstRunner'
}
task RagDoll(type: Javadoc, dependsOn:javadoc) {
doFirst {
options.addStringOption("ragroot", "./src/main/jastadd")
}
group = "documentation"
description = 'create a RagDoll documentation'
classpath = javadoc.classpath
destinationDir = javadoc.destinationDir
excludes = javadoc.excludes
executable = javadoc.executable
failOnError = false
includes = javadoc.includes
options.doclet = "ragdoll.RagDollDoclet"
options.docletpath = files('libs/RagDoll.jar').asList()
source = javadoc.source
options.linkSource = true
// title not working for some reason
title = ""
doLast {
println "Visit: file://" + destinationDir + "/index.html"
}
}
jastadd {
configureModuleBuild()
modules "jastadd_modules"
module = "expressions"
extraJastAddOptions = ['--cache=none']
astPackage = 'de.tudresden.inf.st.mquat.jastadd.model'
genDir = 'src/gen/java'
buildInfoDir = 'src/gen-res'
parser.name = 'MquatParser'
scanner.genDir = "src/gen/java/de/tudresden/inf/st/mquat/jastadd/scanner"
parser.genDir = "src/gen/java/de/tudresden/inf/st/mquat/jastadd/parser"
}
/*
This filter is autogenerated.
- Add the name of the filters you want to use in the configs block.
- Write the name of the node types you want to see in the AST inside your filters.
. Add a : to the begining of each name.
. Child classes of a type will also be included in the graph.
You can filter on attributes and AST-position, show attributes in the graph and style the nodes.
see https://bitbucket.org/jastadd/jastadddebugger-exjobb/wiki/The%20Filter%20Configuration%20Language
for full documentation.
*/
configs{
use = include;
}
filter include{
/**/
:ASTNode{
when{}
subtree{}
show{}
style{}
}
/**/
}
module("expressions") {
java {
basedir "src/main/java/"
include "**/*.java"
}
jastadd {
basedir "src/main/jastadd/"
include "**/*.ast"
include "**/*.jadd"
include "**/*.jrag"
}
scanner {
include "src/main/jastadd/mquat.flex"
}
parser {
include "src/main/jastadd/mquat.parser"
}
}
\ No newline at end of file
/**
* contains a method to display a debug text output of the AST
*/
aspect ASTPrinting {
public String ASTNode.getASTString() {
String result = this.getClass().getSimpleName() + "\n";
for (java.lang.reflect.Method method : this.getClass().getMethods()) {
ASTNodeAnnotation.Token annotation = method.getAnnotation(ASTNodeAnnotation.Token.class);
if (annotation != null) {
try {
result += "|--" + annotation.name() + ": " + method.invoke(this);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (java.lang.reflect.InvocationTargetException e) {
e.printStackTrace();
}
result += "\n";
}
}
for(int childIndex = 0; childIndex < getNumChildNoTransform(); childIndex++) {
ASTNode<?> child = getChildNoTransform(childIndex);
String childString = "NULL\n";
if(child != null) {
childString = child.getASTString();
}
if(childIndex < getNumChildNoTransform() - 1) {
childString = childString.replaceAll("(?m)^", "| ");
} else {
childString = childString.replaceAll("(?m)^", " ");
}
result += "|\n|--" + childString.substring(3);
}
return result;
}
}
/**
* This aspect contains commonly used attributes to easier navigate the model
*/
aspect Analysis {
syn boolean Clause.isRequiringClause() = getClauseType() == ClauseType.REQUIRING;
syn boolean Clause.isProvidingClause() = getClauseType() == ClauseType.PROVIDING;
inh boolean Designator.inProvidingClause();
eq Root.getSoftwareModel().inProvidingClause() = false;
eq Clause.getExpression().inProvidingClause() = isProvidingClause();
eq Clause.getDesignator().inProvidingClause() = isProvidingClause();
inh boolean Designator.inRequiringClause();
eq Root.getSoftwareModel().inRequiringClause() = false;
eq Clause.getExpression().inRequiringClause() = isRequiringClause();
eq Clause.getDesignator().inRequiringClause() = isRequiringClause();
}
aspect Clauses {
uncache Clause.checkUsing(Assignment assignment);
syn boolean Clause.checkUsing(Assignment assignment) {
double leftSide = getDesignator().evalUsing(assignment);
double rightSide = getExpression().evalUsing(assignment);
switch (getClauseComparator()) {
case LT:
return leftSide < rightSide;
case LE:
return leftSide <= rightSide;
case EQ:
return leftSide == rightSide;
case NE:
return leftSide != rightSide;
case GE:
return leftSide >= rightSide;
case GT:
return leftSide > rightSide;
}
throw new RuntimeException("Unknown clause comparator. This should never happen!");
}
}
\ No newline at end of file
aspect Enums {
public enum PropertyAggregation {
SUM,
MAX
}
public enum ClauseType {
REQUIRING,
PROVIDING
}
public enum ClauseComparator {
LT { public String symbol() { return "<"; } },
LE { public String symbol() { return "<="; } },
EQ { public String symbol() { return "="; } },
NE { public String symbol() { return "!="; } },
GE { public String symbol() { return ">="; } },
GT { public String symbol() { return ">"; } };
public String symbol() { throw new AbstractMethodError(); }
}
}
aspect eval {
uncache Clause.checkUsing(Request request, Resource resource);
syn boolean Clause.checkUsing(Request request, Resource resource) = checkUsing(simpleAssignment(request, resource));
syn double Expression.evalAsDouble();
eq LiteralExpression.evalAsDouble() = getValue();
eq ParenthesizedExpression.evalAsDouble() = getExpression().evalAsDouble();
eq AddExpression.evalAsDouble() = getLeft().evalAsDouble() + getRight().evalAsDouble();
eq SubExpression.evalAsDouble() = getLeft().evalAsDouble() - getRight().evalAsDouble();
eq MultExpression.evalAsDouble() = getLeft().evalAsDouble() * getRight().evalAsDouble();
eq DivExpression.evalAsDouble() = getLeft().evalAsDouble() / getRight().evalAsDouble();
eq PowerExpression.evalAsDouble() = Math.pow(getLeft().evalAsDouble(), getRight().evalAsDouble());
syn double Designator.evalAsDouble();
eq QualifiedNameDesignator.evalAsDouble() {
throw new RuntimeException("This attribute should not be called because a QualifiedNameDesignator is a temporary node!");
}
eq SoftwareDesignator.evalAsDouble() {
throw new RuntimeException("TODO implement ParentResourceDesignator.evalAsDouble()");
}
eq PropertyResourceDesignator.evalAsDouble() {
if (inRequiringClause()) {
// TODO
}
throw new RuntimeException("TODO implement PropertyResourceDesignator.evalAsDouble()");
}
eq MetaParameterDesignator.evalAsDouble() {
throw new RuntimeException("TODO implement MetaParameterDesignator.evalAsDouble()");
}
uncache Clause.evalUsing(Request request, Resource target);
syn double Clause.evalUsing(Request request, Resource target) = evalUsing(simpleAssignment(request, target));
// eval using for assignments
uncache Clause.evalUsing(Assignment assignment);
syn double Clause.evalUsing(Assignment assignment) = getExpression().evalUsing(assignment);
uncache Expression.evalUsing(Assignment assignment);
syn double Expression.evalUsing(Assignment assignment);
eq LiteralExpression.evalUsing(Assignment assignment) = getValue();
eq ParenthesizedExpression.evalUsing(Assignment assignment) = getExpression().evalUsing(assignment);
eq AddExpression.evalUsing(Assignment assignment) = getLeft().evalUsing(assignment) + getRight().evalUsing(assignment);
eq SubExpression.evalUsing(Assignment assignment) = getLeft().evalUsing(assignment) - getRight().evalUsing(assignment);
eq MultExpression.evalUsing(Assignment assignment) = getLeft().evalUsing(assignment) * getRight().evalUsing(assignment);
eq DivExpression.evalUsing(Assignment assignment) = getLeft().evalUsing(assignment) / getRight().evalUsing(assignment);
eq PowerExpression.evalUsing(Assignment assignment) = Math.pow(getLeft().evalUsing(assignment), getRight().evalUsing(assignment));
uncache Designator.evalUsing(Assignment assignment);
syn double Designator.evalUsing(Assignment assignment);
eq QualifiedNameDesignator.evalUsing(Assignment assignment) {
throw new RuntimeException("This attribute should not be called because a QualifiedNameDesignator is a temporary node!");
}
eq SoftwareDesignator.evalUsing(Assignment assignment) {
Assignment providingAssignment;
if (this.hasInstanceRef()) {
// referencing a required component
providingAssignment = assignment.mappedAssignment(this.getInstanceRef().getRef());
} else {
// use given implementation for resolving
providingAssignment = assignment;
}
if (providingAssignment == null) {
MquatWriteSettings settings = new MquatWriteSettings("");
logger.error("Could not evaluate {} in {} of {}",
this.print(settings), containingClause().print(settings),
((ModelElement)containingClause().getParent()).name());
return 0;
}
for (Clause clause : providingAssignment.getImplementation().getClauseList()) {
if (clause.isProvidingClause()) {
if (clause.getDesignator().isSoftwareDesignator()) {
SoftwareDesignator sd = clause.getDesignator().asSoftwareDesignator();
if (!sd.hasInstanceRef()) {
if (sd.getPropertyRef().getRef().equals(this.getPropertyRef().getRef())) {
return clause.getExpression().evalUsing(providingAssignment);
}
// found another provision clause with a different property
}
}
}
}
throw new RuntimeException("this should not be happening!");
}
eq PropertyResourceDesignator.evalUsing(Assignment assignment) {
Resource resource = assignment.mappedResource(this.getInstanceRef().getRef());
return resource.getCurrentValueByProperty(this.getPropertyRef().getRef());
}
eq MetaParameterDesignator.evalUsing(Assignment assignment) {
LiteralExpression litExp = assignment.getRequest().getMetaParameterExpression(getMetaParameterRef().getRef());
if (litExp != null) {
// TODO could also using evalAsDouble here
return litExp.evalUsing(assignment);
}
logger.error("evalUsing: Request did not have assignment for meta {}, returning 0", getMetaParameterRef().name());
return 0;
}
rewrite QualifiedNameDesignator {
to Designator {
MquatWriteSettings settings = new MquatWriteSettings(" ");
return containingClause().resolveQualifiedName(this.getQualifiedName());
}
}
}
// Expression Language
abstract Expression ;
LiteralExpression:Expression ::= <Value:double> ;
// variation point of the expression language:
abstract Designator:Expression ;
ParenthesizedExpression:Expression ::= Expression ;
abstract BinaryExpression:Expression ::= Left:Expression Right:Expression ;
AddExpression:BinaryExpression ;
SubExpression:BinaryExpression ;
MultExpression:BinaryExpression ;
DivExpression:BinaryExpression ;
PowerExpression:BinaryExpression ;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment