Git Product home page Git Product logo

gips's Introduction

GIPS

GIPS is an open-source framework for Graph-Based ILP Problem Specification.

Installation (development)

  • Install AdoptOpenJDK 17 (HotSpot JVM) or newer.
  • Install eMoflon::IBeX as described here.
  • Install at least one of the supported ILP solvers:
    • Install Gurobi in version 11.0.1 and activate a license for your computer.
      • Currently, Gurobi is the default ILP solver used in GIPS because of the great performance.
    • Install GLPK in the newest version (4.6.5) and add it to your path.
      • GLPK is an open-source ILP solver that can be used without a charge.
    • Install CPLEX in version 22.1.1 and activate a license for your computer (if neccessary).
      • CPLEX is a commercial alternative to the other ILP solvers implemented in GIPS.
  • Clone this Git repository to your local machine and import it into Eclipse: File -> Import -> General -> Existing Projects into Workspace. Import all projects.
    • As an alternative, you can use this PSF file for the import.
  • Inside the Eclipse development workspace ...
    • ... Run Run all GIPS MWE2 files.launch from org.emoflon.gips.core/launch with right click Run As -> Build all GIPS MWE2 files.
    • ... build all projects (Project -> Clean... -> Clean all projects) to trigger code generation.
  • Launch a runtime workspace (while using a runtime Eclipse) as stated in the eMoflon::IBeX installation steps to start using GIPS.

A good start point to verify your installation is to run some of the GIPS examples or the GIPS tests.

Code-Style

This project uses the built-in code-style and code-formatter of Eclipse. Before contributing, please set-up your Eclipse code-style settings as follows:

  • Window -> Preferences -> Java
    • -> Code Style -> Clean Up -> Active profile: -> "Eclipse [built-in]" (default)
    • -> Code Style -> Formatter -> Active profile: -> "Eclipse [built-in]" (default)
    • -> Code Style -> _Organize Imports: -> "java, javax, org, com" (default)
    • -> Editor -> _Save Actions:
      • Check "Perform the selected actions on save"
      • Check "Format source code"
      • Check "Format all lines"
      • Check "Organize imports"
      • Check "Additional actions"

By using this settings, you should be unable to commit unformatted code.

Installation (user)

  • Install AdoptOpenJDK 17 (HotSpot JVM) or newer.
  • Install eMoflon::IBeX as described here.
  • Install at least one of the supported ILP solvers:
    • Install Gurobi in version 11.0.1 and activate a license for your computer.
      • Currently, Gurobi is the default ILP solver used in GIPS because of the great performance.
    • Install GLPK in the newest version (4.6.5) and add it to your path.
      • GLPK is an open-source ILP solver that can be used without a charge.
    • Install CPLEX in version 22.1.1 and activate a license for your computer (if neccessary).
      • CPLEX is a commercial alternative to the other ILP solvers implemented in GIPS.
  • Install GIPS from the public Eclipse update site: https://echtzeitsysteme.github.io/gips-updatesite/snapshot/updatesite/
  • Launch a runtime workspace (while using a runtime Eclipse) as stated in the eMoflon::IBeX installation steps to start using GIPS.

Usage (running simulations)

Please refer to the GIPS examples reposiory.

Tests

Please refer to the GIPS tests repository.

License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for more details.

gips's People

Contributors

arg0n1s avatar flipy91 avatar maxkratz avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

gips's Issues

Validator: At least use `self` once per sub-constraint

The validator must forbid any sub-constraints that do not contain any self reference. Example:

constraint -> pattern::vnodeNotMapped {
	mappings.n2n->filter(m | m.nodes().snode.resourceAmountAvailable > 0)->count() == 1 & self.nodes().vnode.resourceDemand > 0
}```

java.lang.IllegalArgumentException: Context must be used at least once per non-global constraint.
at org.emoflon.gips.build.transformation.GipsToIntermediate.transformConstraint(GipsToIntermediate.java:485)
at org.emoflon.gips.build.transformation.GipsToIntermediate.transformConstraints(GipsToIntermediate.java:349)
at org.emoflon.gips.build.transformation.GipsToIntermediate.transform(GipsToIntermediate.java:86)
at org.emoflon.gips.build.GipsProjectBuilder.build(GipsProjectBuilder.java:46)

Validator: Check if a stream expression terminal produces a boolean, double or collection

Validator: Check if a stream expression terminal produces a boolean, double or collection. In the latter case an error must be thrown!

Example:

patterns.networkRule->filter(m2 | m2.nodes().root != null & self.nodes().virtualLink != m2.nodes().root)

-> If this statement is the sole statement within a constraint or objective, the validator has to complain! This can not be translated to neither, an ILP constraint nor an ILP objective.

Newly created projects do not show correct package structure when created outside of the workspace

I'm unsure if this is a bug in Eclipse because I cannot find any difference in, e.g., MANIFEST.MF, .project etc.
However, supposes one creates a new GIPSL project and chooses a location outside of the current workspace (e.g., to create a new project in an existing git repository). In that case, Eclipse does not display the package hierarchy inside src-gen correctly.
Therefore, all builds of the generated code fail.

image

GIPS(L) package validator detects non-existing duplicates on Linux

Currently, the GIPS(L) package validator detects non-existing duplicated packages when GIPS/Eclipse is running on a Linux-based OS.

This can be reproduced, e.g., with the GIPS VM build, temporarily available here: https://github.com/maxkratz/gips-vm/actions/runs/3392757900

GIPSL files without at least one GT pattern/rule throw exceptions when executing

Example GIPSL file:

package "gipsl.all.build.nogt"
import "platform:/resource/gipsl.all.build.model/model/Model.ecore"

config {  
	solver := GLPK [home:="fu", license:="bar"];
	launchConfig := true [main := "TODO"];
	timeLimit := true [value := 10.0];
	randomSeed := true [value := 0];
	presolve := true;
	debugOutput := true;
}

// No GT rules/patterns on purpose

//
// GIPSL starts here!
//

constraint -> class::SubstrateResourceNode {
	self.resourceAmountAvailable >= 0
}

When executing, GIPS throws an exception:

java.lang.ClassNotFoundException: gipsl.all.build.nogt.hipe.engine.HiPEEngine
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:375)
	at org.emoflon.ibex.gt.hipe.runtime.HiPEGTEngine.initEngine(HiPEGTEngine.java:274)
	at org.emoflon.ibex.gt.hipe.runtime.HiPEGTEngine.monitor(HiPEGTEngine.java:266)
	at org.emoflon.ibex.gt.engine.GraphTransformationInterpreter.loadPatternSet(GraphTransformationInterpreter.java:220)
	at org.emoflon.ibex.gt.engine.GraphTransformationInterpreter.loadPatternSet(GraphTransformationInterpreter.java:239)
	at gipsl.all.build.nogt.api.NogtAPI.<init>(NogtAPI.java:35)
	at gipsl.all.build.nogt.api.NogtApp.initAPI(NogtApp.java:42)
	at gipsl.all.build.nogt.api.NogtApp.initAPI(NogtApp.java:1)
	at org.emoflon.gips.core.api.GipsEngineAPI.initInternal(GipsEngineAPI.java:96)
	at gipsl.all.build.nogt.api.gips.NogtGipsAPI.init(NogtGipsAPI.java:24)
	at gipsl.all.build.nogt.connector.NoGtConnector.<init>(NoGtConnector.java:13)
	at test.suite.gipsl.all.build.GipslAllBuildNoGtTest.callableSetUp(GipslAllBuildNoGtTest.java:17)
	at test.suite.gipsl.all.build.GipslAllBuildNoGtTest.testConstraintOk(GipslAllBuildNoGtTest.java:25)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:95)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:91)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:60)
	at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)

Maybe there is some generated code missing:
image

Possible solutions:

  • Fix the bug (if there is one).
  • If it is the intended behavior, the validator should check if the GIPSL file/package contains at least one GT pattern/rule.

Possible bug: Missing matches in some tests of `gipsl.all.build.filter`

See: https://github.com/Echtzeitsysteme/gips-tests/blob/main/gipsl.all.build.filter/src/gipsl/all/build/filter/Model.gipsl

Sometimes, the test testMap2to1NoIsDoubled() (https://github.com/Echtzeitsysteme/gips-tests/blob/main/test.suite.gips/src/test/suite/gipsl/all/build/GipslAllBuildFilterTest.java#L46-L56) fails because some of the matches are missing.

ILP solver output if test passes:

\ LP format - for model browsing. Use MPS format to capture full model detail.
Maximize
  n2n#0 + n2n#1
Subject To
 PatternConstraint1OnvnodeNotMapped_0: n2n#0 = 1
 PatternConstraint1OnvnodeNotMapped_1: n2n#1 = 1
 PatternConstraint0OnvnodeNotMapped_0: n2n#0 + n2n#1 = 1
 PatternConstraint0OnvnodeNotMapped_1: n2n#0 + n2n#1 = 1
Bounds
Binaries
 n2n#0 n2n#1
End

ILP solver output if test fails:

\ LP format - for model browsing. Use MPS format to capture full model detail.
Maximize
  n2n#0 + n2n#1
Subject To
 PatternConstraint0OnvnodeNotMapped_0: n2n#0 + n2n#1 = 1
 PatternConstraint0OnvnodeNotMapped_1: n2n#0 + n2n#1 = 1
Bounds
Binaries
 n2n#0 n2n#1
End

AFAIK, this behaviour is independent from the used pattern matcher (I've also tested it with Democles) and the used ILP solver (GUROBI and GLPK show the same error).

Launch file configuration for CPLEX is broken

Currently, the generated launch file for CPLEX solvers contains the subfolder /lib which is non-existent for CPLEX.

Example GIPSL config:

config {
	solver := CPLEX [home:="/opt/ibm/ILOG/CPLEX_Studio221/cplex/bin/x86-64_linux", license:="bar"];
	launchConfig := true [main := "org.emoflon.gips.gipsl.examples.mdvne.ExampleMdVNE"];
	timeLimit := true [value := 10.0];
	randomSeed := true [value := 0];
	presolve := true;
	debugOutput := true;
}

Generated run file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
	<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
		<listEntry value="/org.emoflon.gips.gipsl.examples.mdvne"/>
	</listAttribute>
	<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
		<listEntry value="4"/>
	</listAttribute>
	<mapAttribute key="org.eclipse.debug.core.environmentVariables">
	    <mapEntry key="GRB_LICENSE_FILE" value="bar"/>
	    <mapEntry key="GUROBI_HOME" value="/opt/ibm/ILOG/CPLEX_Studio221/cplex/bin/x86-64_linux"/>
	    <mapEntry key="LD_LIBRARY_PATH" value="/opt/ibm/ILOG/CPLEX_Studio221/cplex/bin/x86-64_linux/lib/"/>
	    <mapEntry key="PATH" value="/opt/ibm/ILOG/CPLEX_Studio221/cplex/bin/x86-64_linux/bin/"/>
	</mapAttribute>
	<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
	<booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
	<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
	<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
	<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.emoflon.gips.gipsl.examples.mdvne.ExampleMdVNE"/>
	<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value=""/>
	<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.emoflon.gips.gipsl.examples.mdvne"/>
</launchConfiguration>

The correct setting would be something like this:

[...]
<mapAttribute key="org.eclipse.debug.core.environmentVariables">
	    <mapEntry key="LD_LIBRARY_PATH" value="/opt/ibm/ILOG/CPLEX_Studio221/cplex/bin/x86-64_linux/"/>
	    <mapEntry key="PATH" value="/opt/ibm/ILOG/CPLEX_Studio221/cplex/bin/x86-64_linux/bin/"/>
	</mapAttribute>
[...]

Another notice: The license file path is irrelevant for GLPK + CPLEX -> We should make this optional in GIPSL. I'll open an issue for this, too.

`NOT` with operator `==` throws an exception during build time

NOT with operator == creates infeasible ILP problems. Example:

!mappings.n2n->filter(m | m.nodes().snode == self)->count() == 1

Problem:
expr + sub_1 >= 1 but there is somethin missing:
expr - sub_1 <= 1

Update: The build of such a constraint is currently not supported. The transformation throws an exception during build time:

ERROR [build.GipsProjectBuilder::49] - java.lang.UnsupportedOperationException: Currently relational expressions containing the '==' operator can not be part of boolean expressions containing operators other than '&'

GipsEngine: ConcurrentModificationException

This happend while running the test GipslAllBuildFilterTest.testMap2to1NoIsDoubled() (https://github.com/Echtzeitsysteme/gips-tests/blob/main/test.suite.gips/src/test/suite/gipsl/all/build/GipslAllBuildFilterTest.java#L46)

java.util.ConcurrentModificationException: java.util.ConcurrentModificationException
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
	at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:562)
	at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:591)
	at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:689)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:159)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:173)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:765)
	at org.emoflon.gips.core.GipsEngine.buildILPProblem(GipsEngine.java:37)
	at test.suite.gips.utils.AConnector.solve(AConnector.java:26)
	at gipsl.all.build.filter.connector.FilterConnector.run(FilterConnector.java:18)
	at test.suite.gipsl.all.build.GipslAllBuildFilterTest.testMap2to1NoIsDoubled(GipslAllBuildFilterTest.java:53)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:95)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:91)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:60)
	at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.util.ConcurrentModificationException
	at java.base/java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1712)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at org.emoflon.ibex.gt.api.GraphTransformationPattern.findMatches(GraphTransformationPattern.java:176)
	at org.emoflon.gips.core.gt.GipsPatternConstraint.buildConstraints(GipsPatternConstraint.java:31)
	at org.emoflon.gips.core.GipsEngine.lambda$1(GipsEngine.java:37)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
	at java.base/java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1779)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290)
	at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:754)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)

Comparison of strings creates non-compilable code

constraint -> mapping::n2n {
	self.nodes().g.name == self.nodes().h.name
}

produces

	protected double builder_1(final N2nMapping context) {
		return -1.0 * context.getH().getName();
	}
	protected ILPTerm builder_0(final N2nMapping context) {
		return new ILPTerm(context, (double)context.getG().getName());
	}

For reproduction, check out the branch hotfix/validator of the repo GIPS and feature/add-string-comparison-tests of the repo gips-tests.

`notEmpty()` throws an exception while generating code

constraint -> global {
// mappings.n2n->count() >= 1
mappings.n2n->notEmpty()
}

produces an error while generating code:

15:07:46 ERROR [build.GipsProjectBuilder::49] - java.lang.IllegalArgumentException: Some constrains contain invalid values within arithmetic expressions, e.g., boolean values instead of arithmetic values.

(See the code example: https://github.com/Echtzeitsysteme/gips-tests/blob/feature/add-notempty-tests/gipsl.all.build.notempty/src/gipsl/all/build/notempty/Model.gipsl#L42)

`patterns.xy... + mappings... + mappings... == 1` generates non compilable code

patterns.xy->filter(...)->count() + mappings... + mappings... == 1 generates incorrect code (not compilable)

see: https://github.com/Echtzeitsysteme/gips-tests/blob/88cce6c0d97eb8db4488db64a856c884a99de652/gips.sort/src/gipsl/Model.gipsl#L109

(Looks like the code generator tries to generate a builder instead of a constant RHS in this case.)

Rewriting the equation to smth. like mappings... + mappings... == 1 - patterns.xy->filter(...)->count() seems to work.

Validator: `1 == self.nodes()... * 0` throws an exception

The validator throws an exception when comparing a static number with a multiplication that contains a node reference.

Example code:

constraint -> pattern::vnodeNotMapped {
	1 == self.nodes().vnode.resourceDemand * 0
}

Symptom:

java.lang.UnsupportedOperationException: Not yet implemented
	at org.emoflon.gips.gipsl.validation.GipslValidator.getNumberType(GipslValidator.java:1384)
	at org.emoflon.gips.gipsl.validation.GipslValidator.combine(GipslValidator.java:1309)
	at org.emoflon.gips.gipsl.validation.GipslValidator.getEvalTypeFromArithExpr(GipslValidator.java:847)
	at org.emoflon.gips.gipsl.validation.GipslValidator.getEvalTypeDelegate(GipslValidator.java:1221)
	at org.emoflon.gips.gipsl.validation.GipslValidator.getEvalTypeFromBoolExpr(GipslValidator.java:799)
	at org.emoflon.gips.gipsl.validation.GipslConstraintValidator.checkConstraint(GipslConstraintValidator.java:85)
	at org.emoflon.gips.gipsl.validation.GipslValidator.checkConstraint(GipslValidator.java:388)

Possible bug: ILP solver output interpretation (`TIME_OUT`)

(Related to #53.)

Currently, the implementation assumes that Gurobi (and probably also GLPK + CPLEX) has found at least one solution if the status is TIME_LIMIT (after solving).
This may lead to the problem that the solver is unable to calculate a concrete value for each variable which leads to a Gurobi exception at this point: https://github.com/Echtzeitsysteme/gips/blob/master/org.emoflon.gips.core/src/org/emoflon/gips/core/ilp/GurobiSolver.java#L115

We should check if at least one solution is found before we update the values from the ILP problem's solution.

Build exception: Pattern already registered with interpreter

constraint -> class::Entry {
	patterns.findFirst->filter(m | m.nodes().val == self)->count() == 0
}

(Taken from https://github.com/Echtzeitsysteme/gips-tests/blob/feature/snapshot-ilp-sort/gips.sort.patternreg/src/gipsl/Model.gipsl#L24-L26) throws an exception at build time:

java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Pattern already registered with interpreter: org.emoflon.ibex.patternmodel.IBeXPatternModel.impl.IBeXContextPatternImpl@7a66c35a (name: findFirst) (hasCountExpression: false) (documentation: )

GIPSL constraints on supertypes do not generate ILP constraints on subtypes

Serial `filter(...)` expr: In some cases this breaks semantics

In some cases, serial filter(...) expressions break the filter semantics.
Example: Echtzeitsysteme/gips-tests#31

constraint -> global {
	mappings.n2n
	->filter(m | m.nodes().vnode.resourceDemand == 0)
	->filter(m | m.nodes().snode.resourceAmountTotal == 0)
	->count() == 0
}

Problem (if I understand it correctly):
If the first filter expression (in this case ->filter(m | m.nodes().vnode.resourceDemand == 0)) filters nothing out, i.e., the result should not be an empty set, the second filter(...) operation could not be triggered and, therefore, the count() does not evaluate to 0?

Transformation: The function that moves constant terms from the variable side to the constant side does not work properly in all cases

Transformation: The function that moves constant terms from the variable side to the constant side does not work properly in all cases.
-> Example: a + (1-b) + c (1-d)
This equation will not be recognized as problematic and will be ignored by the function. But this will leave constant values within the variable expression and, subsequently, lead to errors in the code templates.

Implication is completely broken

One of the implication tests is failing for all ILP solvers. Maybe there is a bug in the problem generation or the test case is wrong.

GLPK: invalid row length

GLPK ILP solver implementation:

constraint -> global {
	mappings.n2n->sum(m | m.value()) == mappings.n2n->sum(m | m.value())
}

generates an error like this:

glp_set_mat_row: i = 2; len = 20; invalid row length 
Error detected in file ..\src\api\prob1.c at line 763

Rename project and repo to GIPS

We changed the name of the tool (and the language) to "GIPS (Graph-Based ILP Problem Specification Tool)". Therefore, we have to rename lots of $stuff in this repo. At least:

  • The repo itself (I would use small letters only -> gips).
  • The Eclipse (Plug-In) projects.
  • Java Packages.
  • File endings (.rslang -> .gipsl?).
  • Documentation (comments, javadoc etc.).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.