diff --git a/gipsl.all.build.notequal/.classpath b/gipsl.all.build.notequal/.classpath new file mode 100644 index 0000000..8aced94 --- /dev/null +++ b/gipsl.all.build.notequal/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/gipsl.all.build.notequal/.project b/gipsl.all.build.notequal/.project new file mode 100644 index 0000000..d1f7f23 --- /dev/null +++ b/gipsl.all.build.notequal/.project @@ -0,0 +1,25 @@ + + + gipsl.all.build.notequal + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.xtext.ui.shared.xtextBuilder + + + + + + org.emoflon.gips.gipsl.ui.gipsNature + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + org.eclipse.xtext.ui.shared.xtextNature + + diff --git a/gipsl.all.build.notequal/.settings/org.eclipse.jdt.core.prefs b/gipsl.all.build.notequal/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..d4540a5 --- /dev/null +++ b/gipsl.all.build.notequal/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,10 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=17 diff --git a/gipsl.all.build.notequal/META-INF/MANIFEST.MF b/gipsl.all.build.notequal/META-INF/MANIFEST.MF new file mode 100644 index 0000000..7b1260f --- /dev/null +++ b/gipsl.all.build.notequal/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Automatic-Module-Name: gipsl.all.build.notequal +Bundle-ManifestVersion: 2 +Bundle-Name: gipsl.all.build.notequal +Bundle-Vendor: My Company +Bundle-Version: 1.0.0.qualifier +Export-Package: gipsl.all.build.notequal.connector +Import-Package: test.suite.gips.utils +Bundle-SymbolicName: gipsl.all.build.notequal; singleton:=true +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-17 +Require-Bundle: org.emoflon.ibex.common, + org.emoflon.ibex.gt, + org.emoflon.gips.core, + org.emoflon.ibex.gt.democles, + org.emoflon.ibex.gt.hipe, + gipsl.all.build.model;bundle-version="0.0.1" diff --git a/gipsl.all.build.notequal/build.properties b/gipsl.all.build.notequal/build.properties new file mode 100644 index 0000000..14acfb7 --- /dev/null +++ b/gipsl.all.build.notequal/build.properties @@ -0,0 +1,5 @@ +source.. = src/,\ + src-gen/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/gipsl.all.build.notequal/src/gipsl/all/build/notequal/Model.gipsl b/gipsl.all.build.notequal/src/gipsl/all/build/notequal/Model.gipsl new file mode 100644 index 0000000..42711c2 --- /dev/null +++ b/gipsl.all.build.notequal/src/gipsl/all/build/notequal/Model.gipsl @@ -0,0 +1,61 @@ +package "gipsl.all.build.notequal" +import "platform:/resource/gipsl.all.build.model/model/Model.ecore" + +config { + solver := GLPK [home:="fu", license:="bar"]; + timeLimit := true [value := 10.0]; + randomSeed := true [value := 0]; + presolve := true; + debugOutput := true; +} + +rule mapVnode { + root: Root { + -containers -> substrateContainer + -containers -> virtualContainer + } + + substrateContainer: SubstrateContainer { + -substrateNodes -> snode + } + + virtualContainer: VirtualContainer { + -virtualNodes -> vnode + } + + snode: SubstrateResourceNode { + ++ -guests -> vnode + } + + vnode: VirtualResourceNode { + ++ -host -> snode + } + + # vnode.resourceDemand <= snode.resourceAmountAvailable + # snode.resourceAmountAvailable >= 0 +} + +// +// GIPSL starts here! +// + +mapping n2n with mapVnode; + +// These two constraints should be equivalent + +// NOT ...->count() == 1 +constraint -> class::SubstrateResourceNode { + !mappings.n2n->filter(m | m.nodes().snode == self)->count() == 1 +} +// ...->count() != 1 +constraint -> class::SubstrateResourceNode { + mappings.n2n->filter(m | m.nodes().snode == self)->count() != 1 +} + +objective nObj -> mapping::n2n { + 1 +} + +global objective : max { + nObj +} diff --git a/gipsl.all.build.notequal/src/gipsl/all/build/notequal/connector/NotEqualConnector.java b/gipsl.all.build.notequal/src/gipsl/all/build/notequal/connector/NotEqualConnector.java new file mode 100644 index 0000000..daf2a87 --- /dev/null +++ b/gipsl.all.build.notequal/src/gipsl/all/build/notequal/connector/NotEqualConnector.java @@ -0,0 +1,25 @@ +package gipsl.all.build.notequal.connector; + +import org.emoflon.gips.core.ilp.ILPSolverOutput; + +import gipsl.all.build.notequal.api.gips.NotequalGipsAPI; +import test.suite.gips.utils.AConnector; +import test.suite.gips.utils.GipsTestUtils; +import test.suite.gips.utils.GlobalTestConfig; + +public class NotEqualConnector extends AConnector { + + public NotEqualConnector(final String modelPath) { + api = new NotequalGipsAPI(); + api.init(GipsTestUtils.pathToAbsUri(modelPath)); + GlobalTestConfig.overrideSolver(api); + } + + @Override + public ILPSolverOutput run(final String outputPath) { + final ILPSolverOutput output = solve(); + ((NotequalGipsAPI) api).getN2n().applyNonZeroMappings(); + return output; + } + +} diff --git a/test.suite.gips/META-INF/MANIFEST.MF b/test.suite.gips/META-INF/MANIFEST.MF index c6e0952..86886a9 100644 --- a/test.suite.gips/META-INF/MANIFEST.MF +++ b/test.suite.gips/META-INF/MANIFEST.MF @@ -36,6 +36,7 @@ Import-Package: gips.generic.scheduling.connector, gipsl.all.build.implicationstatic.connector, gipsl.all.build.inheritedtypecontext.connector, gipsl.all.build.nogt.connector, + gipsl.all.build.notequal.connector, gipsl.all.build.objective.connector, gipsl.all.build.objective.max.connector, gipsl.all.build.objective.scaling.connector, diff --git a/test.suite.gips/src/test/suite/gipsl/all/build/GipslAllBuildNotEqualTest.java b/test.suite.gips/src/test/suite/gipsl/all/build/GipslAllBuildNotEqualTest.java new file mode 100644 index 0000000..d28e43d --- /dev/null +++ b/test.suite.gips/src/test/suite/gipsl/all/build/GipslAllBuildNotEqualTest.java @@ -0,0 +1,51 @@ +package test.suite.gipsl.all.build; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.emoflon.gips.core.ilp.ILPSolverOutput; +import org.emoflon.gips.core.ilp.ILPSolverStatus; +import org.junit.jupiter.api.Test; + +import gipsl.all.build.notequal.connector.NotEqualConnector; + +public class GipslAllBuildNotEqualTest extends AGipslAllBuildTest { + + // Setup method + + public void callableSetUp() { + gen.persistModel(MODEL_PATH); + con = new NotEqualConnector(MODEL_PATH); + } + + // Actual tests + + @Test + public void testMap1to1() { + gen.genSubstrateNode("s1", 1); + gen.genVirtualNode("v1", 1); + callableSetUp(); + + final ILPSolverOutput ret = con.run(OUTPUT_PATH); + + assertEquals(ILPSolverStatus.OPTIMAL, ret.status()); + // v1 must not be mapped because it is forbidden by the constraint + // (either more than one or 0 mappings per substrate node are allowed) + assertEquals(0, Math.abs(ret.objectiveValue())); + } + + @Test + public void testMap2to1() { + gen.genSubstrateNode("s1", 1); + gen.genVirtualNode("v1", 1); + gen.genVirtualNode("v2", 1); + callableSetUp(); + + final ILPSolverOutput ret = con.run(OUTPUT_PATH); + + assertEquals(ILPSolverStatus.OPTIMAL, ret.status()); + // Both virtual nodes must be mapped because there is more than one mapping onto + // the same substrate node possible + assertEquals(2, Math.abs(ret.objectiveValue())); + } + +}