diff options
author | Kristóf Marussy <marussy@mit.bme.hu> | 2020-06-25 19:55:10 +0200 |
---|---|---|
committer | Kristóf Marussy <marussy@mit.bme.hu> | 2020-06-25 19:55:10 +0200 |
commit | c3a6d4b9cf3657070d180aa65ddbf0459e880329 (patch) | |
tree | 780c4fc61578dcb309af53fb0c164c7627e51676 /Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse | |
parent | New configuration language parser WIP (diff) | |
parent | Scope unsat benchmarks (diff) | |
download | VIATRA-Generator-c3a6d4b9cf3657070d180aa65ddbf0459e880329.tar.gz VIATRA-Generator-c3a6d4b9cf3657070d180aa65ddbf0459e880329.tar.zst VIATRA-Generator-c3a6d4b9cf3657070d180aa65ddbf0459e880329.zip |
Merge branch 'kris'
Diffstat (limited to 'Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse')
3 files changed, 247 insertions, 0 deletions
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse/CpsStateCoder.xtend b/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse/CpsStateCoder.xtend new file mode 100644 index 00000000..223cee03 --- /dev/null +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse/CpsStateCoder.xtend | |||
@@ -0,0 +1,134 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.domains.cps.dse | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.domains.cps.ApplicationInstance | ||
4 | import hu.bme.mit.inf.dslreasoner.domains.cps.CyberPhysicalSystem | ||
5 | import hu.bme.mit.inf.dslreasoner.domains.cps.HostInstance | ||
6 | import hu.bme.mit.inf.dslreasoner.domains.cps.HostType | ||
7 | import hu.bme.mit.inf.dslreasoner.domains.cps.Request | ||
8 | import hu.bme.mit.inf.dslreasoner.domains.cps.Requirement | ||
9 | import org.eclipse.emf.common.notify.Notifier | ||
10 | import org.eclipse.emf.ecore.resource.Resource | ||
11 | import org.eclipse.emf.ecore.resource.ResourceSet | ||
12 | import org.eclipse.viatra.dse.statecode.IStateCoder | ||
13 | import org.eclipse.viatra.dse.statecode.IStateCoderFactory | ||
14 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
15 | import org.eclipse.xtend2.lib.StringConcatenationClient | ||
16 | |||
17 | class CpsStateCoder implements IStateCoder { | ||
18 | CyberPhysicalSystem cps | ||
19 | |||
20 | protected new() { | ||
21 | } | ||
22 | |||
23 | override init(Notifier notifier) { | ||
24 | cps = switch (notifier) { | ||
25 | ResourceSet: getCpsFromResourceSet(notifier) | ||
26 | Resource: getCpsFromResource(notifier) | ||
27 | CyberPhysicalSystem: notifier | ||
28 | default: throw new IllegalArgumentException("notifier is not a CyberPhysicalSystem") | ||
29 | } | ||
30 | } | ||
31 | |||
32 | private def getCpsFromResourceSet(ResourceSet resourceSet) { | ||
33 | if (resourceSet.resources.empty) { | ||
34 | throw new IllegalArgumentException("No Resource in ResourceSet") | ||
35 | } | ||
36 | val resource = resourceSet.resources.head | ||
37 | getCpsFromResource(resource) | ||
38 | } | ||
39 | |||
40 | private def getCpsFromResource(Resource resource) { | ||
41 | if (resource.contents.empty) { | ||
42 | throw new IllegalArgumentException("No EObject in Resource") | ||
43 | } | ||
44 | val cps = resource.contents.head | ||
45 | if (cps instanceof CyberPhysicalSystem) { | ||
46 | cps | ||
47 | } else { | ||
48 | throw new IllegalArgumentException("EObject in Resource is not a CyberPhysicalSystem") | ||
49 | } | ||
50 | } | ||
51 | |||
52 | override String createStateCode() { | ||
53 | '''«createRequestsCode»«createHostTypesCode»''' | ||
54 | } | ||
55 | |||
56 | private def StringConcatenationClient createRequestsCode() { | ||
57 | '''«FOR request : cps.requests»«createRequestCode(request)»«ENDFOR»''' | ||
58 | } | ||
59 | |||
60 | private def StringConcatenationClient createRequestCode(Request request) { | ||
61 | '''[«FOR requirement : request.requirements»«createRequirementCode(requirement)»«ENDFOR»]''' | ||
62 | } | ||
63 | |||
64 | private def StringConcatenationClient createRequirementCode(Requirement requirement) { | ||
65 | '''[«FOR app : requirement.instances SEPARATOR ","»«createAppCode(app)»«ENDFOR»]''' | ||
66 | } | ||
67 | |||
68 | private def createAppCode(ApplicationInstance app) { | ||
69 | if (app.allocatedTo === null) { | ||
70 | "-" | ||
71 | } else { | ||
72 | createMatchArgumentCode(app.allocatedTo) | ||
73 | } | ||
74 | } | ||
75 | |||
76 | private def createHostTypesCode() { | ||
77 | '''(«FOR hostType : cps.hostTypes SEPARATOR ","»«hostType.instances.size»«ENDFOR»)''' | ||
78 | } | ||
79 | |||
80 | override String createActivationCode(IPatternMatch match) { | ||
81 | '''«match.specification.simpleName»(«FOR arg : match.toArray SEPARATOR ","»«createMatchArgumentCode(arg)»«ENDFOR»)''' | ||
82 | } | ||
83 | |||
84 | protected dispatch def String createMatchArgumentCode(Requirement requirement) { | ||
85 | val request = requirement.eContainer | ||
86 | if (request instanceof Request) { | ||
87 | if (request.eContainer != cps) { | ||
88 | throw new IllegalArgumentException("Request is not contained in the CPS") | ||
89 | } | ||
90 | val requestIndex = cps.requests.indexOf(request) | ||
91 | val requirementIndex = request.requirements.indexOf(requirement) | ||
92 | requestIndex + "." + requirementIndex | ||
93 | } else { | ||
94 | throw new IllegalArgumentException("Requirement is not contained in a request") | ||
95 | } | ||
96 | } | ||
97 | |||
98 | protected dispatch def String createMatchArgumentCode(ApplicationInstance app) { | ||
99 | val requirement = app.requirement | ||
100 | if (requirement === null) { | ||
101 | throw new IllegalArgumentException("Application instance is not associated with a requirement") | ||
102 | } | ||
103 | val instanceIndex = requirement.instances.indexOf(app) | ||
104 | createMatchArgumentCode(requirement) + "." + instanceIndex | ||
105 | } | ||
106 | |||
107 | protected dispatch def String createMatchArgumentCode(HostInstance host) { | ||
108 | val hostType = host.eContainer | ||
109 | if (hostType instanceof HostType) { | ||
110 | val hostIndex = hostType.instances.indexOf(host) | ||
111 | createMatchArgumentCode(hostType) + "." + hostIndex | ||
112 | } else { | ||
113 | throw new IllegalArgumentException("Host is not contained in a host type") | ||
114 | } | ||
115 | } | ||
116 | |||
117 | protected dispatch def String createMatchArgumentCode(HostType hostType) { | ||
118 | if (hostType.eContainer != cps) { | ||
119 | throw new IllegalArgumentException("Host type is not contained in the CPS") | ||
120 | } | ||
121 | val hostTypeIndex = cps.hostTypes.indexOf(hostType) | ||
122 | hostTypeIndex.toString | ||
123 | } | ||
124 | |||
125 | protected dispatch def createMatchArgumentCode(Object object) { | ||
126 | throw new IllegalArgumentException("Unknown match argument: ") | ||
127 | } | ||
128 | |||
129 | static class Factory implements IStateCoderFactory { | ||
130 | override createStateCoder() { | ||
131 | new CpsStateCoder | ||
132 | } | ||
133 | } | ||
134 | } | ||
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse/RuleBasedCpsMain.xtend b/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse/RuleBasedCpsMain.xtend new file mode 100644 index 00000000..35b3b1df --- /dev/null +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse/RuleBasedCpsMain.xtend | |||
@@ -0,0 +1,39 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.domains.cps.dse | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.domains.cps.CpsPackage | ||
4 | import hu.bme.mit.inf.dslreasoner.domains.cps.generator.CpsGenerator | ||
5 | import hu.bme.mit.inf.dslreasoner.domains.cps.queries.CpsQueries | ||
6 | import org.eclipse.emf.ecore.EPackage | ||
7 | import org.eclipse.emf.ecore.EStructuralFeature | ||
8 | import org.eclipse.emf.ecore.resource.Resource | ||
9 | import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl | ||
10 | import org.eclipse.viatra.addon.querybasedfeatures.runtime.QueryBasedFeatureSettingDelegateFactory | ||
11 | import org.eclipse.viatra.addon.querybasedfeatures.runtime.handler.QueryBasedFeatures | ||
12 | import org.eclipse.viatra.dse.api.DesignSpaceExplorer | ||
13 | import org.eclipse.viatra.dse.api.DesignSpaceExplorer.DseLoggingLevel | ||
14 | import org.eclipse.viatra.query.runtime.extensibility.SingletonQueryGroupProvider | ||
15 | import org.eclipse.viatra.query.runtime.registry.QuerySpecificationRegistry | ||
16 | import org.eclipse.viatra.query.runtime.registry.connector.QueryGroupProviderSourceConnector | ||
17 | |||
18 | class RuleBasedCpsMain { | ||
19 | private new() { | ||
20 | new IllegalStateException("This is a static utility class and should not be instantiated directly.") | ||
21 | } | ||
22 | |||
23 | public static def void main(String[] args) { | ||
24 | DesignSpaceExplorer.turnOnLogging(DseLoggingLevel.VERBOSE_FULL) | ||
25 | Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put(Resource.Factory.Registry.DEFAULT_EXTENSION, | ||
26 | new XMIResourceFactoryImpl) | ||
27 | EStructuralFeature.Internal.SettingDelegate.Factory.Registry.INSTANCE.put(QueryBasedFeatures.ANNOTATION_SOURCE, | ||
28 | new QueryBasedFeatureSettingDelegateFactory) | ||
29 | EPackage.Registry.INSTANCE.put(CpsPackage.eNS_URI, CpsPackage.eINSTANCE) | ||
30 | QuerySpecificationRegistry.instance.addSource( | ||
31 | new QueryGroupProviderSourceConnector("CpsQueries", new SingletonQueryGroupProvider(CpsQueries.instance), | ||
32 | true)) | ||
33 | val generator = new CpsGenerator(1, 4, 1) | ||
34 | val problem = generator.generateCpsProblem | ||
35 | // problem.eResource.save(emptyMap) | ||
36 | val solver = new RuleBasedCpsSolver | ||
37 | solver.solve(problem) | ||
38 | } | ||
39 | } | ||
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse/RuleBasedCpsSolver.xtend b/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse/RuleBasedCpsSolver.xtend new file mode 100644 index 00000000..503c06ea --- /dev/null +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/dse/RuleBasedCpsSolver.xtend | |||
@@ -0,0 +1,74 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.domains.cps.dse | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.domains.cps.CpsFactory | ||
4 | import hu.bme.mit.inf.dslreasoner.domains.cps.CpsPackage | ||
5 | import hu.bme.mit.inf.dslreasoner.domains.cps.CyberPhysicalSystem | ||
6 | import hu.bme.mit.inf.dslreasoner.domains.cps.queries.Allocate | ||
7 | import hu.bme.mit.inf.dslreasoner.domains.cps.queries.AverageFreeHddMetric | ||
8 | import hu.bme.mit.inf.dslreasoner.domains.cps.queries.AverageFreeMemoryMetric | ||
9 | import hu.bme.mit.inf.dslreasoner.domains.cps.queries.CostMetric | ||
10 | import hu.bme.mit.inf.dslreasoner.domains.cps.queries.CreateHostInstance | ||
11 | import hu.bme.mit.inf.dslreasoner.domains.cps.queries.GuidanceObjective | ||
12 | import hu.bme.mit.inf.dslreasoner.domains.cps.queries.RequirementNotSatisfied | ||
13 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.CompositeDirectionalThresholdObjective | ||
14 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind | ||
15 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold | ||
16 | import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.QueryBasedObjective | ||
17 | import org.eclipse.viatra.dse.api.DesignSpaceExplorer | ||
18 | import org.eclipse.viatra.dse.evolutionary.EvolutionaryStrategyBuilder | ||
19 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory | ||
20 | |||
21 | class RuleBasedCpsSolver { | ||
22 | extension val BatchTransformationRuleFactory = new BatchTransformationRuleFactory | ||
23 | extension val CpsFactory = CpsFactory.eINSTANCE | ||
24 | |||
25 | def solve(CyberPhysicalSystem problem) { | ||
26 | // for (request : problem.requests) { | ||
27 | // for (req : request.requirements) { | ||
28 | // for (i : 0 ..< req.count) { | ||
29 | // val app = createApplicationInstance | ||
30 | // req.type.instances += app | ||
31 | // req.instances += app | ||
32 | // } | ||
33 | // } | ||
34 | // } | ||
35 | val dse = new DesignSpaceExplorer | ||
36 | dse.addMetaModelPackage(CpsPackage.eINSTANCE) | ||
37 | dse.initialModel = problem.eResource.resourceSet | ||
38 | dse.addTransformationRule(createRule.precondition(RequirementNotSatisfied.instance).action [ | ||
39 | val app = createApplicationInstance | ||
40 | req.type.instances += app | ||
41 | req.instances += app | ||
42 | ].build) | ||
43 | dse.addTransformationRule(createRule.precondition(Allocate.instance).action [ | ||
44 | app.allocatedTo = host | ||
45 | ].build) | ||
46 | // dse.addTransformationRule(createRule(UnallocateAppInstance.instance).action [ | ||
47 | // app.allocatedTo = null | ||
48 | // ].build) | ||
49 | dse.addTransformationRule(createRule.precondition(CreateHostInstance.instance).action [ | ||
50 | hostType.instances += createHostInstance | ||
51 | ].build) | ||
52 | // dse.addTransformationRule(createRule(RemoveHostInstance.instance).action [ | ||
53 | // hostInstance.type.instances -= hostInstance | ||
54 | // ].build) | ||
55 | dse.addObjective( | ||
56 | new CompositeDirectionalThresholdObjective("Composite", | ||
57 | new QueryBasedObjective(GuidanceObjective.instance, ObjectiveKind.LOWER_IS_BETTER, | ||
58 | new ObjectiveThreshold.Inclusive(0), 0), | ||
59 | new QueryBasedObjective(AverageFreeMemoryMetric.instance, ObjectiveKind.LOWER_IS_BETTER, | ||
60 | new ObjectiveThreshold.Inclusive(0.75), 0), | ||
61 | new QueryBasedObjective(AverageFreeHddMetric.instance, ObjectiveKind.LOWER_IS_BETTER, | ||
62 | new ObjectiveThreshold.Inclusive(0.75), 0))) | ||
63 | dse.addObjective( | ||
64 | new QueryBasedObjective(CostMetric.instance, ObjectiveKind.LOWER_IS_BETTER, | ||
65 | ObjectiveThreshold.NO_THRESHOLD, 0)) | ||
66 | dse.maxNumberOfThreads = 1 | ||
67 | dse.stateCoderFactory = new CpsStateCoder.Factory | ||
68 | val strategy = EvolutionaryStrategyBuilder.createNsga2Strategy(25) | ||
69 | dse.startExplorationWithTimeout(strategy, 2 * 60 * 1000) | ||
70 | for (solution : dse.solutions) { | ||
71 | println("Found solution: " + solution.stateCode + " " + solution.arbitraryTrajectory.fitness) | ||
72 | } | ||
73 | } | ||
74 | } | ||