diff options
Diffstat (limited to 'Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner')
9 files changed, 463 insertions, 211 deletions
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/CostObjective.xtend b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/CostObjective.xtend new file mode 100644 index 00000000..3a8688e9 --- /dev/null +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/CostObjective.xtend | |||
@@ -0,0 +1,13 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.domains.satellite.mdeo | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.domains.satellite.queries.CostMetric | ||
4 | |||
5 | class CostObjective extends MetricBasedGuidanceFunction { | ||
6 | new() { | ||
7 | super(CostMetric.instance) | ||
8 | } | ||
9 | |||
10 | override getName() { | ||
11 | "Cost" | ||
12 | } | ||
13 | } | ||
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/ExcludedOptimisationInterpreter.xtend b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/ExcludedOptimisationInterpreter.xtend new file mode 100644 index 00000000..ddf5748e --- /dev/null +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/ExcludedOptimisationInterpreter.xtend | |||
@@ -0,0 +1,85 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.domains.satellite.mdeo | ||
2 | |||
3 | import java.util.Properties | ||
4 | import org.moeaframework.Executor | ||
5 | import org.moeaframework.Instrumenter | ||
6 | import org.moeaframework.algorithm.PeriodicAction | ||
7 | import org.moeaframework.core.TerminationCondition | ||
8 | import org.moeaframework.core.spi.AlgorithmFactory | ||
9 | import uk.ac.kcl.inf.mdeoptimiser.interfaces.cli.Run | ||
10 | import uk.ac.kcl.inf.mdeoptimiser.languages.mopt.Optimisation | ||
11 | import uk.ac.kcl.inf.mdeoptimiser.languages.mopt.SolverSpec | ||
12 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.OptimisationInterpreter | ||
13 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.executor.SolutionGenerator | ||
14 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.moea.MoeaOptimisation | ||
15 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.moea.algorithms.MoeaOptimisationAlgorithmProvider | ||
16 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.moea.instrumentation.PopulationCollector | ||
17 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.moea.problem.MoeaOptimisationProblem | ||
18 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.operators.adaptation.MutationStepSizeStrategyFactory | ||
19 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.output.MDEOBatch | ||
20 | |||
21 | class ExcludedMoeaOptimisation extends MoeaOptimisation { | ||
22 | SolutionGenerator solutionGenerator | ||
23 | Instrumenter algorithmStepSizeInstrumenter | ||
24 | |||
25 | override execute(SolverSpec solverSpec, SolutionGenerator solutionGenerator) { | ||
26 | this.solutionGenerator = solutionGenerator | ||
27 | super.execute(solverSpec, solutionGenerator) | ||
28 | } | ||
29 | |||
30 | override Instrumenter runOptimisation(SolverSpec solverSpec, Properties optimisationProperties) { | ||
31 | val algorithmFactory = new AlgorithmFactory | ||
32 | algorithmFactory.addProvider(new MoeaOptimisationAlgorithmProvider) | ||
33 | |||
34 | algorithmStepSizeInstrumenter = new Instrumenter().addExcludedPackage("org.eclipse").withProblemClass( | ||
35 | MoeaOptimisationProblem, solutionGenerator).attachApproximationSetCollector().attachElapsedTimeCollector(). | ||
36 | attachPopulationSizeCollector.attach(new PopulationCollector()).withFrequency(1).withFrequencyType( | ||
37 | PeriodicAction.FrequencyType.STEPS) | ||
38 | |||
39 | var stepSizeStrategy = new MutationStepSizeStrategyFactory(solverSpec.algorithm, algorithmStepSizeInstrumenter). | ||
40 | strategy | ||
41 | |||
42 | solutionGenerator.setMutationStepSizeStrategy(stepSizeStrategy) | ||
43 | |||
44 | // TODO: Place this in a better location. | ||
45 | // Exclude JDK packages from Instrumenter | ||
46 | this.algorithmStepSizeInstrumenter.addExcludedPackage("jdk") | ||
47 | |||
48 | new Executor().usingAlgorithmFactory(algorithmFactory).withAlgorithm(solverSpec.algorithm.name) // Initialize problem with our solution generator | ||
49 | .withProblemClass(MoeaOptimisationProblem, solutionGenerator).withProperties(optimisationProperties). | ||
50 | withInstrumenter(algorithmStepSizeInstrumenter).withTerminationCondition( | ||
51 | optimisationProperties.get("terminationCondition") as TerminationCondition).run() | ||
52 | |||
53 | return algorithmStepSizeInstrumenter | ||
54 | } | ||
55 | } | ||
56 | |||
57 | class ExcludedOptimisationInterpreter extends OptimisationInterpreter { | ||
58 | val Optimisation model | ||
59 | |||
60 | new(String projectPath, Optimisation model) { | ||
61 | super(projectPath, model) | ||
62 | this.model = model | ||
63 | } | ||
64 | |||
65 | override start() { | ||
66 | // This model provider loads the model given by the user in the DSL | ||
67 | var solutionGenerator = new SolutionGenerator(model, getBreedingOperators, getMutationOperators, | ||
68 | getModelProvider, getMetamodel); | ||
69 | |||
70 | return new ExcludedMoeaOptimisation().execute(model.solver, solutionGenerator) | ||
71 | } | ||
72 | |||
73 | } | ||
74 | |||
75 | class ExcludedRun extends Run { | ||
76 | override runBatch(String moptProjectPath, Optimisation optimisationModel, Integer batch, boolean singleBatch) { | ||
77 | val optimisationInterpreter = new ExcludedOptimisationInterpreter(moptProjectPath, optimisationModel); | ||
78 | val startTime = System.nanoTime(); | ||
79 | val optimisationOutcome = optimisationInterpreter.start(); | ||
80 | val endTime = System.nanoTime(); | ||
81 | val experimentDuration = ((endTime - startTime) / 1000000); | ||
82 | val generatedRules = optimisationInterpreter.getRulegenOperators(); | ||
83 | return new MDEOBatch(batch, experimentDuration, optimisationOutcome, generatedRules, singleBatch); | ||
84 | } | ||
85 | } | ||
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/LocalSearchEngineManager.xtend b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/LocalSearchEngineManager.xtend new file mode 100644 index 00000000..ee7f0060 --- /dev/null +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/LocalSearchEngineManager.xtend | |||
@@ -0,0 +1,31 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.domains.satellite.mdeo | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.domains.satellite.queries.SatelliteQueries | ||
4 | import java.util.WeakHashMap | ||
5 | import org.eclipse.emf.ecore.EObject | ||
6 | import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine | ||
7 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine | ||
8 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngineOptions | ||
9 | import org.eclipse.viatra.query.runtime.emf.EMFScope | ||
10 | import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.LocalSearchHints | ||
11 | |||
12 | class LocalSearchEngineManager { | ||
13 | public static val INSTANCE = new LocalSearchEngineManager | ||
14 | |||
15 | val WeakHashMap<EObject, ViatraQueryEngine> engineMap = new WeakHashMap | ||
16 | |||
17 | private new() { | ||
18 | } | ||
19 | |||
20 | def getEngine(EObject eObject) { | ||
21 | engineMap.computeIfAbsent(eObject) [ | ||
22 | val scope = new EMFScope(it) | ||
23 | val localSearchHints = LocalSearchHints.^default.build | ||
24 | val options = ViatraQueryEngineOptions.defineOptions.withDefaultHint(localSearchHints).withDefaultBackend( | ||
25 | localSearchHints.queryBackendFactory).build | ||
26 | val engine = AdvancedViatraQueryEngine.on(scope, options) | ||
27 | SatelliteQueries.instance.prepare(engine) | ||
28 | engine | ||
29 | ] | ||
30 | } | ||
31 | } | ||
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/MetricBasedGuidanceFunction.xtend b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/MetricBasedGuidanceFunction.xtend new file mode 100644 index 00000000..1529794f --- /dev/null +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/MetricBasedGuidanceFunction.xtend | |||
@@ -0,0 +1,47 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.domains.satellite.mdeo | ||
2 | |||
3 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
4 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | ||
5 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
6 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.IGuidanceFunction | ||
7 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.interpreter.guidance.Solution | ||
8 | |||
9 | abstract class MetricBasedGuidanceFunction implements IGuidanceFunction { | ||
10 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification | ||
11 | |||
12 | protected new(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> querySpecification) { | ||
13 | this.querySpecification = querySpecification | ||
14 | if (querySpecification.parameters.size != 1) { | ||
15 | throw new IllegalArgumentException("Metric must have a single parameter") | ||
16 | } | ||
17 | } | ||
18 | |||
19 | override computeFitness(Solution model) { | ||
20 | val value = getMetricValue(model) | ||
21 | computeFitness(value) | ||
22 | } | ||
23 | |||
24 | protected def double computeFitness(double metricValue) { | ||
25 | metricValue | ||
26 | } | ||
27 | |||
28 | private def getMetricValue(Solution solution) { | ||
29 | val model = solution.model | ||
30 | val queryEngine = LocalSearchEngineManager.INSTANCE.getEngine(model) | ||
31 | val matcher = querySpecification.getMatcher(queryEngine) | ||
32 | val iterator = matcher.allMatches.iterator | ||
33 | if (!iterator.hasNext) { | ||
34 | throw new IllegalStateException("Too few matches") | ||
35 | } | ||
36 | val objectValue = iterator.next.get(0) | ||
37 | if (objectValue instanceof Number) { | ||
38 | val doubleValue = objectValue.doubleValue | ||
39 | if (iterator.hasNext) { | ||
40 | throw new IllegalStateException("Too many matches") | ||
41 | } | ||
42 | doubleValue | ||
43 | } else { | ||
44 | throw new IllegalStateException("Metric value must be a number") | ||
45 | } | ||
46 | } | ||
47 | } | ||
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/PatternMatchConstraint.xtend b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/PatternMatchConstraint.xtend new file mode 100644 index 00000000..b238e64f --- /dev/null +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/PatternMatchConstraint.xtend | |||
@@ -0,0 +1,29 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.domains.satellite.mdeo | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import hu.bme.mit.inf.dslreasoner.domains.satellite.queries.SatelliteQueries | ||
5 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.IGuidanceFunction | ||
6 | import uk.ac.kcl.inf.mdeoptimiser.libraries.core.optimisation.interpreter.guidance.Solution | ||
7 | |||
8 | class PatternMatchConstraint implements IGuidanceFunction { | ||
9 | static val CONSTRAINT_ANNOTATION_NAME = "Constraint" | ||
10 | |||
11 | val queries = ImmutableList.copyOf(SatelliteQueries.instance.specifications.filter [ | ||
12 | allAnnotations.exists[name == CONSTRAINT_ANNOTATION_NAME] | ||
13 | ]) | ||
14 | |||
15 | override getName() { | ||
16 | "PatternMatch" | ||
17 | } | ||
18 | |||
19 | override computeFitness(Solution solution) { | ||
20 | val model = solution.model | ||
21 | val queryEngine = LocalSearchEngineManager.INSTANCE.getEngine(model) | ||
22 | var int matchCount = 0 | ||
23 | for (query : queries) { | ||
24 | val matcher = query.getMatcher(queryEngine) | ||
25 | matchCount += matcher.countMatches | ||
26 | } | ||
27 | matchCount | ||
28 | } | ||
29 | } | ||
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/SatelliteMdeOptimiserMain.xtend b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/SatelliteMdeOptimiserMain.xtend new file mode 100644 index 00000000..c5a30f94 --- /dev/null +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/SatelliteMdeOptimiserMain.xtend | |||
@@ -0,0 +1,52 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.domains.satellite.mdeo | ||
2 | |||
3 | import java.io.BufferedReader | ||
4 | import java.io.BufferedWriter | ||
5 | import java.io.FileReader | ||
6 | import java.io.FileWriter | ||
7 | import java.util.Map | ||
8 | import org.eclipse.emf.ecore.EPackage | ||
9 | import org.eclipse.emf.ecore.resource.Resource | ||
10 | import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl | ||
11 | import satellite.SatellitePackage | ||
12 | import uk.ac.kcl.inf.mdeoptimiser.languages.MoptStandaloneSetup | ||
13 | |||
14 | class SatelliteMdeOptimiserMain { | ||
15 | static val PROJECT_PATH = "." | ||
16 | static val MOPT_PATH = "src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/satellite.mopt" | ||
17 | |||
18 | private new() { | ||
19 | new IllegalStateException("This is a static utility class and should not be instantiated directly.") | ||
20 | } | ||
21 | |||
22 | public static def void main(String[] args) { | ||
23 | Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put(Resource.Factory.Registry.DEFAULT_EXTENSION, | ||
24 | new XMIResourceFactoryImpl) | ||
25 | EPackage.Registry.INSTANCE.put(SatellitePackage.eNS_URI, SatellitePackage.eINSTANCE) | ||
26 | fixupHenshinModel("model/satellite.henshin", "model/satellite_fixup.henshin", | ||
27 | #{"satellite.ecore" -> SatellitePackage.eNS_URI}) | ||
28 | val injector = new MoptStandaloneSetup().createInjectorAndDoEMFRegistration(); | ||
29 | injector.getInstance(ExcludedRun).run(PROJECT_PATH, MOPT_PATH) | ||
30 | } | ||
31 | |||
32 | private def static void fixupHenshinModel(String originalPath, String outputPath, Map<String, String> remapMap) { | ||
33 | val reader = new BufferedReader(new FileReader(originalPath)) | ||
34 | try { | ||
35 | val writer = new BufferedWriter(new FileWriter(outputPath)) | ||
36 | try { | ||
37 | var String line | ||
38 | while ((line = reader.readLine) !== null) { | ||
39 | for (entry : remapMap.entrySet) { | ||
40 | line = line.replace(entry.key, entry.value) | ||
41 | } | ||
42 | writer.write(line) | ||
43 | writer.write("\n") | ||
44 | } | ||
45 | } finally { | ||
46 | writer.close | ||
47 | } | ||
48 | } finally { | ||
49 | reader.close | ||
50 | } | ||
51 | } | ||
52 | } | ||
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/satellite.mopt b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/satellite.mopt new file mode 100644 index 00000000..138ea309 --- /dev/null +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/mdeo/satellite.mopt | |||
@@ -0,0 +1,35 @@ | |||
1 | problem { | ||
2 | basepath <model> | ||
3 | metamodel <satellite.SatellitePackage> | ||
4 | model <../inputs/SatelliteInstance.xmi> | ||
5 | } | ||
6 | |||
7 | goal { | ||
8 | objective Cost minimise java { "hu.bme.mit.inf.dslreasoner.domains.satellite.mdeo.CostObjective" } | ||
9 | constraint PatternMatch java { "hu.bme.mit.inf.dslreasoner.domains.satellite.mdeo.PatternMatchConstraint" } | ||
10 | } | ||
11 | |||
12 | search { | ||
13 | mutate using <satellite_fixup.henshin> unit "addCubeSat3U" | ||
14 | // mutate { "CubeSat3U" } | ||
15 | // mutate { "CubeSat6U" } | ||
16 | // mutate { "SmallSat" } | ||
17 | // mutate { "InterferometryPayload" } | ||
18 | // mutate { "CommSubsystem" } | ||
19 | // mutate { "DirectedCommunicationLink" } | ||
20 | } | ||
21 | |||
22 | solver { | ||
23 | optimisation provider moea algorithm NSGAII { | ||
24 | variation: mutation | ||
25 | population: 25 | ||
26 | mutation.step: 3 | ||
27 | mutation.strategy: random | ||
28 | } | ||
29 | |||
30 | termination { | ||
31 | time: 120 | ||
32 | } | ||
33 | |||
34 | batches 1 | ||
35 | } \ No newline at end of file | ||
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/queries/SatelliteQueries.vql b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/queries/SatelliteQueries.vql index 9b77ef72..557c1172 100644 --- a/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/queries/SatelliteQueries.vql +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/queries/SatelliteQueries.vql | |||
@@ -55,28 +55,42 @@ private pattern indirectLinkAllowed(From : Spacecraft, To : CommunicatingElement | |||
55 | } | 55 | } |
56 | 56 | ||
57 | private pattern linkAllowed(From : Spacecraft, To : CommunicatingElement) { | 57 | private pattern linkAllowed(From : Spacecraft, To : CommunicatingElement) { |
58 | find matchingAntenna(From, To, _); | 58 | find matchingAntenna(From, To); |
59 | neg find cubeSat3U(From); | 59 | neg find cubeSat3U(From); |
60 | } or { | 60 | } or { |
61 | find matchingAntenna(From, To, TransceiverBand::UHF); | 61 | find matchingAntenna(From, To); |
62 | CubeSat3U(From); | 62 | CubeSat3U(From); |
63 | } or { | 63 | } or { |
64 | find matchingAntenna(From, To, _); | 64 | find matchingAntenna(From, To); |
65 | CubeSat3U(From); | 65 | CubeSat3U(From); |
66 | GroundStationNetwork(To); | 66 | GroundStationNetwork(To); |
67 | } | 67 | } |
68 | 68 | ||
69 | private pattern matchingAntenna(From : Spacecraft, To : CommunicatingElement, Band : TransceiverBand) { | 69 | private pattern matchingAntenna(From : Spacecraft, To : CommunicatingElement) { |
70 | CommunicatingElement.commSubsystem.band(From, Band); | 70 | CommunicatingElement.commSubsystem(From, FromSys); |
71 | CommunicatingElement.commSubsystem.band(To, Band); | 71 | CommunicatingElement.commSubsystem(To, ToSys); |
72 | CommunicatingElement.commSubsystem.gain(From, Gain); | 72 | find matchingCommSubsystem(FromSys, ToSys); |
73 | CommunicatingElement.commSubsystem.gain(To, Gain); | 73 | } |
74 | |||
75 | private pattern matchingCommSubsystem(From : CommSubsystem, To : CommSubsystem) { | ||
76 | UHFCommSubsystem(From); | ||
77 | UHFCommSubsystem(To); | ||
78 | } or { | ||
79 | XCommSubsystem(From); | ||
80 | XCommSubsystem(To); | ||
81 | } or { | ||
82 | KaCommSubsystem(From); | ||
83 | KaCommSubsystem(To); | ||
74 | } | 84 | } |
75 | 85 | ||
76 | private pattern cubeSat3U(Sat : CubeSat3U) { | 86 | private pattern cubeSat3U(Sat : CubeSat3U) { |
77 | CubeSat3U(Sat); | 87 | CubeSat3U(Sat); |
78 | } | 88 | } |
79 | 89 | ||
90 | private pattern cubeSat6U(Sat : CubeSat6U) { | ||
91 | CubeSat6U(Sat); | ||
92 | } | ||
93 | |||
80 | // No communication loops may exist | 94 | // No communication loops may exist |
81 | // No spacecraft may directly communicate with itself | 95 | // No spacecraft may directly communicate with itself |
82 | 96 | ||
@@ -104,63 +118,7 @@ private pattern directCommunicationLink(Source : CommunicatingElement, Target : | |||
104 | pattern incompatibleSourceAndTargetBand(Link : DirectedCommunicationLink) { | 118 | pattern incompatibleSourceAndTargetBand(Link : DirectedCommunicationLink) { |
105 | DirectedCommunicationLink.source(Link, SourceSubsystem); | 119 | DirectedCommunicationLink.source(Link, SourceSubsystem); |
106 | DirectedCommunicationLink.target(Link, TargetSubsystem); | 120 | DirectedCommunicationLink.target(Link, TargetSubsystem); |
107 | CommSubsystem.band(SourceSubsystem, Band); | 121 | neg find matchingCommSubsystem(SourceSubsystem, TargetSubsystem); |
108 | neg find commSubsystemBand(TargetSubsystem, Band); | ||
109 | } | ||
110 | |||
111 | private pattern commSubsystemBand(Comm : CommSubsystem, Band : TransceiverBand) { | ||
112 | CommSubsystem.band(Comm, Band); | ||
113 | } | ||
114 | |||
115 | @Constraint(severity = "error", key = {Link}, | ||
116 | message = "Two ends of a communication link must use the same antenna gain.") | ||
117 | pattern incompatibleSourceAndTargetGain(Link : DirectedCommunicationLink) { | ||
118 | DirectedCommunicationLink.source(Link, SourceSubsystem); | ||
119 | DirectedCommunicationLink.target(Link, TargetSubsystem); | ||
120 | CommSubsystem.gain(SourceSubsystem, Gain); | ||
121 | neg find commSubsystemGain(TargetSubsystem, Gain); | ||
122 | } | ||
123 | |||
124 | private pattern commSubsystemGain(Comm : CommSubsystem, Gain : AntennaGain) { | ||
125 | CommSubsystem.gain(Comm, Gain); | ||
126 | } | ||
127 | |||
128 | // UHF-band transmitters may only be combined with a low gain antenna | ||
129 | |||
130 | @Constraint(severity = "error", key = {Comm}, | ||
131 | message = "UHF transceiver must be combined with a low gain antenna.") | ||
132 | pattern uhfAntennaGainNotLow(Comm : CommSubsystem) { | ||
133 | CommSubsystem.band(Comm, TransceiverBand::UHF); | ||
134 | // VIATRA will fail to infer a type constraint for the virtual variable introduced | ||
135 | // when an enum literal appears in a negative pattern call, so we use a helper pattern | ||
136 | // instead of neg find commSubsystemGain(Comm, AntennaGain::LOW); | ||
137 | neg find commSubsystemGainLow(Comm); | ||
138 | } | ||
139 | |||
140 | private pattern commSubsystemGainLow(Comm : CommSubsystem) { | ||
141 | CommSubsystem.gain(Comm, AntennaGain::LOW); | ||
142 | } | ||
143 | |||
144 | // X-band transmitters may only be combined with a medium gain antenna | ||
145 | |||
146 | @Constraint(severity = "error", key = {Comm}, | ||
147 | message = "X-band transceiver must be combined with a medium gain antenna.") | ||
148 | pattern xAntennaGainNotMedium(Comm : CommSubsystem) { | ||
149 | CommSubsystem.band(Comm, TransceiverBand::X); | ||
150 | neg find commSubsystemGainMedium(Comm); | ||
151 | } | ||
152 | |||
153 | private pattern commSubsystemGainMedium(Comm : CommSubsystem) { | ||
154 | CommSubsystem.gain(Comm, AntennaGain::MEDIUM); | ||
155 | } | ||
156 | |||
157 | // Ka-band transmitters may only be combined with a medium or high gain antenna | ||
158 | |||
159 | @Constraint(severity = "error", key = {Comm}, | ||
160 | message = "Ka-band transceiver must be combined with a medium or high gain antenna.") | ||
161 | pattern kaAntennaGainLow(Comm : CommSubsystem) { | ||
162 | CommSubsystem.band(Comm, TransceiverBand::Ka); | ||
163 | CommSubsystem.gain(Comm, AntennaGain::LOW); | ||
164 | } | 122 | } |
165 | 123 | ||
166 | // 3U CubeSats are assumed to only be able to downlink to Earth using an X-band trasmitter, | 124 | // 3U CubeSats are assumed to only be able to downlink to Earth using an X-band trasmitter, |
@@ -177,8 +135,8 @@ pattern threeUCubeSatWithNonUhfCrossLink(Sat : CubeSat3U) { | |||
177 | neg find groundStationNetwork(Target); | 135 | neg find groundStationNetwork(Target); |
178 | } | 136 | } |
179 | 137 | ||
180 | private pattern commSubsystemBandUhf(Comm : CommSubsystem) { | 138 | private pattern commSubsystemBandUhf(Comm : UHFCommSubsystem) { |
181 | CommSubsystem.band(Comm, TransceiverBand::UHF); | 139 | UHFCommSubsystem(Comm); |
182 | } | 140 | } |
183 | 141 | ||
184 | private pattern groundStationNetwork(Network : GroundStationNetwork) { | 142 | private pattern groundStationNetwork(Network : GroundStationNetwork) { |
@@ -190,7 +148,8 @@ private pattern groundStationNetwork(Network : GroundStationNetwork) { | |||
190 | @Constraint(severity = "error", key = {Spacecraft}, | 148 | @Constraint(severity = "error", key = {Spacecraft}, |
191 | message = "Only a Small Satellite can be configured with a Ka-band communication system.") | 149 | message = "Only a Small Satellite can be configured with a Ka-band communication system.") |
192 | pattern cubeSatWithKaAntenna(Spacecraft : Spacecraft) { | 150 | pattern cubeSatWithKaAntenna(Spacecraft : Spacecraft) { |
193 | CommunicatingElement.commSubsystem.band(Spacecraft, TransceiverBand::Ka); | 151 | CommunicatingElement.commSubsystem(Spacecraft, Comm); |
152 | KaCommSubsystem(Comm); | ||
194 | neg find smallSat(Spacecraft); | 153 | neg find smallSat(Spacecraft); |
195 | } | 154 | } |
196 | 155 | ||
@@ -198,146 +157,147 @@ pattern smallSat(Sat : SmallSat) { | |||
198 | SmallSat(Sat); | 157 | SmallSat(Sat); |
199 | } | 158 | } |
200 | 159 | ||
201 | @QueryBasedFeature(feature = "kind") | 160 | //// |
202 | pattern spacecraftOfKind(Spacecraft : Spacecraft, Kind : SpacecraftKind) { | 161 | //// Metrics |
203 | CubeSat3U(Spacecraft); | 162 | //// |
204 | Kind == SpacecraftKind::CubeSat3U; | ||
205 | } or { | ||
206 | CubeSat6U(Spacecraft); | ||
207 | Kind == SpacecraftKind::CubeSat6U; | ||
208 | } or { | ||
209 | SmallSat(Spacecraft); | ||
210 | Kind == SpacecraftKind::SmallSat; | ||
211 | } | ||
212 | |||
213 | |||
214 | // | 163 | // |
215 | // Metrics | 164 | //// Coverage |
216 | // | 165 | // |
217 | 166 | //pattern coverageMetric(Coverage : java Double) { | |
218 | // Coverage | 167 | // Coverage == sum find missionCoverage(_, #_); |
219 | 168 | //} | |
220 | pattern coverageMetric(Coverage : java Double) { | 169 | // |
221 | Coverage == sum find missionCoverage(_, #_); | 170 | //private pattern missionCoverage(Mission : InterferometryMission, Coverage : java Double) { |
222 | } | 171 | // InterferometryMission.observationTime(Mission, ObservationTime); |
223 | 172 | // ObserverCount == count find spacecraftWithInterferometryPayload(Mission, _); | |
224 | private pattern missionCoverage(Mission : InterferometryMission, Coverage : java Double) { | 173 | // Coverage == eval(Math.pow(1 - 2.0 / ObserverCount, 1 + 9 * (1.0 / ObservationTime)) + 0.05 * ObservationTime / 3); |
225 | InterferometryMission.observationTime(Mission, ObservationTime); | 174 | //} |
226 | ObserverCount == count find spacecraftWithInterferometryPayload(Mission, _); | 175 | // |
227 | Coverage == eval(Math.pow(1 - 2.0 / ObserverCount, 1 + 9 * (1.0 / ObservationTime)) + 0.05 * ObservationTime / 3); | 176 | //// Time |
228 | } | 177 | // |
229 | 178 | //pattern timeMetric(Time : java Double) { | |
230 | // Time | 179 | // Time == sum find missionTime(_, #_); |
231 | 180 | //} | |
232 | pattern timeMetric(Time : java Double) { | 181 | // |
233 | Time == sum find missionTime(_, #_); | 182 | //private pattern missionTime(Mission : InterferometryMission, Time : java Double) { |
234 | } | 183 | // InterferometryMission.observationTime(Mission, ObservationTime); |
235 | 184 | // TrasmitTime == sum find transmitTime(Mission, _, #_); | |
236 | private pattern missionTime(Mission : InterferometryMission, Time : java Double) { | 185 | // Time == eval(TrasmitTime + 60.0 * ObservationTime); |
237 | InterferometryMission.observationTime(Mission, ObservationTime); | 186 | //} |
238 | TrasmitTime == sum find transmitTime(Mission, _, #_); | 187 | // |
239 | Time == eval(TrasmitTime + 60.0 * ObservationTime); | 188 | //private pattern transmitTime(Mission : InterferometryMission, Spacecraft : Spacecraft, TransmitTime : java Double) { |
240 | } | 189 | // ConstellationMission.spacecraft(Mission, Spacecraft); |
241 | 190 | // find scienceData(Spacecraft, ScienceData); | |
242 | private pattern transmitTime(Mission : InterferometryMission, Spacecraft : Spacecraft, TransmitTime : java Double) { | 191 | // IncomingData == sum find incomingData(Spacecraft, _, #_); |
243 | ConstellationMission.spacecraft(Mission, Spacecraft); | 192 | // find transmitRate(Spacecraft, TransmitRate); |
244 | find scienceData(Spacecraft, ScienceData); | 193 | // TransmitTime == eval((ScienceData + IncomingData) / (7.5 * TransmitRate)); |
245 | IncomingData == sum find incomingData(Spacecraft, _, #_); | 194 | //} |
246 | find transmitRate(Spacecraft, TransmitRate); | 195 | // |
247 | TransmitTime == eval((ScienceData + IncomingData) / (7.5 * TransmitRate)); | 196 | //private pattern incomingData(Spacecraft : Spacecraft, Source : Spacecraft, Data : java Double) { |
248 | } | 197 | // find indirectCommunicationLink(Source, Spacecraft); |
249 | 198 | // find scienceData(Source, Data); | |
250 | private pattern incomingData(Spacecraft : Spacecraft, Source : Spacecraft, Data : java Double) { | 199 | //} |
251 | find indirectCommunicationLink(Source, Spacecraft); | 200 | // |
252 | find scienceData(Source, Data); | 201 | //private pattern scienceData(Spacecraft : Spacecraft, Data : java Double) { |
253 | } | 202 | // ConstellationMission.spacecraft(Mission, Spacecraft); |
254 | 203 | // InterferometryMission.observationTime(Mission, ObservationTime); | |
255 | private pattern scienceData(Spacecraft : Spacecraft, Data : java Double) { | 204 | // Data == eval(12.0 * ObservationTime); |
256 | ConstellationMission.spacecraft(Mission, Spacecraft); | 205 | //} |
257 | InterferometryMission.observationTime(Mission, ObservationTime); | 206 | // |
258 | Data == eval(12.0 * ObservationTime); | 207 | //private pattern transmitRate(Spacecraft : Spacecraft, TransmitRate : java Double) { |
259 | } | 208 | // find spacecraftUplink(Spacecraft, Comm, Target); |
260 | 209 | // UHFCommSubsystem(Comm); | |
261 | private pattern transmitRate(Spacecraft : Spacecraft, TransmitRate : java Double) { | 210 | // Spacecraft(Target); |
262 | find spacecraftUplink(Spacecraft, TransceiverBand::UHF, Target); | 211 | // TransmitRate == 5.0; |
263 | Spacecraft(Target); | 212 | //} or { |
264 | TransmitRate == 5.0; | 213 | // find spacecraftUplink(Spacecraft, Comm, Target); |
265 | } or { | 214 | // XCommSubsystem(Comm); |
266 | find spacecraftUplink(Spacecraft, TransceiverBand::X, Target); | 215 | // Spacecraft(Target); |
267 | Spacecraft(Target); | 216 | // TransmitRate == 1.6; |
268 | TransmitRate == 1.6; | 217 | //} or { |
269 | } or { | 218 | // find spacecraftUplink(Spacecraft, Comm, Target); |
270 | find spacecraftUplink(Spacecraft, TransceiverBand::X, Target); | 219 | // XCommSubsystem(Comm); |
271 | GroundStationNetwork(Target); | 220 | // GroundStationNetwork(Target); |
272 | TransmitRate == 0.7; | 221 | // TransmitRate == 0.7; |
273 | } or { | 222 | //} or { |
274 | find spacecraftUplink(Spacecraft, TransceiverBand::Ka, Target); | 223 | // find spacecraftUplink(Spacecraft, Comm, Target); |
275 | Spacecraft(Target); | 224 | // KaCommSubsystem(Comm); |
276 | TransmitRate == 220.0; | 225 | // Spacecraft(Target); |
277 | } or { | 226 | // TransmitRate == 220.0; |
278 | find spacecraftUplink(Spacecraft, TransceiverBand::Ka, Target); | 227 | //} or { |
279 | GroundStationNetwork(Target); | 228 | // find spacecraftUplink(Spacecraft, Comm, Target); |
280 | TransmitRate == 80.0; | 229 | // KaCommSubsystem(Comm); |
281 | } | 230 | // GroundStationNetwork(Target); |
282 | 231 | // TransmitRate == 80.0; | |
283 | private pattern spacecraftUplink(Spacecraft : Spacecraft, Band : TransceiverBand, Target : CommunicatingElement) { | 232 | //} |
284 | CommunicatingElement.communicationLink(Spacecraft, Link); | 233 | // |
285 | DirectedCommunicationLink.source.band(Link, Band); | 234 | //private pattern spacecraftUplink(Spacecraft : Spacecraft, TargetSubsystem : CommSubsystem, Target : CommunicatingElement) { |
286 | DirectedCommunicationLink.target(Link, TargetSubsystem); | 235 | // CommunicatingElement.communicationLink(Spacecraft, Link); |
287 | CommunicatingElement.commSubsystem(Target, TargetSubsystem); | 236 | // DirectedCommunicationLink.target(Link, TargetSubsystem); |
288 | } | 237 | // CommunicatingElement.commSubsystem(Target, TargetSubsystem); |
289 | 238 | //} | |
290 | // Cost | 239 | // |
291 | 240 | //// Cost | |
292 | pattern costMetric(Cost : java Double) { | 241 | // |
293 | Cost == sum find missionCost(_, #_); | 242 | //pattern costMetric(Cost : java Double) { |
294 | } | 243 | // Cost == sum find missionCost(_, #_); |
295 | 244 | //} | |
296 | private pattern missionCost(Mission : InterferometryMission, Cost : java Double) { | 245 | // |
297 | InterferometryMission.observationTime(Mission, ObservationTime); | 246 | //private pattern missionCost(Mission : InterferometryMission, Cost : java Double) { |
298 | SpacecraftCost == sum find spacecraftCost(Mission, _, #_); | 247 | // InterferometryMission.observationTime(Mission, ObservationTime); |
299 | Cost == eval(SpacecraftCost + 100000.0 * ObservationTime); | 248 | // SpacecraftCost == sum find spacecraftCost(Mission, _, #_); |
300 | } | 249 | // Cost == eval(SpacecraftCost + 100000.0 * ObservationTime); |
301 | 250 | //} | |
302 | private pattern spacecraftCost(Mission : InterferometryMission, Spacecraft : Spacecraft, Cost : java Double) { | 251 | // |
303 | ConstellationMission.spacecraft(Mission, Spacecraft); | 252 | //private pattern spacecraftCost(Mission : InterferometryMission, Spacecraft : Spacecraft, Cost : java Double) { |
304 | find spacecraftOfKind(Spacecraft, Kind); | 253 | // ConstellationMission.spacecraft(Mission, Spacecraft); |
305 | KindCount == count find spacecraftOfKind(_, Kind); | 254 | // find spacecraftOfKindCount(Spacecraft, KindCount); |
306 | find basePrice(Spacecraft, BasePrice); | 255 | // find basePrice(Spacecraft, BasePrice); |
307 | find interferometryPayloadCost(Spacecraft, InterferometryPayloadCost); | 256 | // find interferometryPayloadCost(Spacecraft, InterferometryPayloadCost); |
308 | find additionalCommSubsystemCost(Spacecraft, AdditionalCommSubsystemCost); | 257 | // find additionalCommSubsystemCost(Spacecraft, AdditionalCommSubsystemCost); |
309 | Cost == eval(BasePrice * Math.pow(KindCount, -0.25) + InterferometryPayloadCost + AdditionalCommSubsystemCost); | 258 | // Cost == eval(BasePrice * Math.pow(KindCount, -0.25) + InterferometryPayloadCost + AdditionalCommSubsystemCost); |
310 | } | 259 | //} |
311 | 260 | // | |
312 | private pattern basePrice(Spacecraft : Spacecraft, BasePrice : java Double) { | 261 | //private pattern spacecraftOfKindCount(Sat : Spacecraft, Count : java Integer) { |
313 | CubeSat3U(Spacecraft); | 262 | // CubeSat3U(Sat); |
314 | BasePrice == 250000.0; | 263 | // Count == count find cubeSat3U(_); |
315 | } or { | 264 | //} or { |
316 | CubeSat6U(Spacecraft); | 265 | // CubeSat6U(Sat); |
317 | BasePrice == 750000.0; | 266 | // Count == count find cubeSat6U(_); |
318 | } or { | 267 | //} or { |
319 | SmallSat(Spacecraft); | 268 | // SmallSat(Sat); |
320 | BasePrice == 3000000.0; | 269 | // Count == count find smallSat(_); |
321 | } | 270 | //} |
322 | 271 | // | |
323 | private pattern interferometryPayloadCost(Spacecraft : Spacecraft, Cost : java Double) { | 272 | //private pattern basePrice(Spacecraft : Spacecraft, BasePrice : java Double) { |
324 | find spacecraftWithInterferometryPayload(_, Spacecraft); | 273 | // CubeSat3U(Spacecraft); |
325 | Cost == 50000.0; | 274 | // BasePrice == 250000.0; |
326 | } or { | 275 | //} or { |
327 | neg find spacecraftWithInterferometryPayload(_, Spacecraft); | 276 | // CubeSat6U(Spacecraft); |
328 | Cost == 0.0; | 277 | // BasePrice == 750000.0; |
329 | } | 278 | //} or { |
330 | 279 | // SmallSat(Spacecraft); | |
331 | private pattern additionalCommSubsystemCost(Spacecraft : Spacecraft, Cost : java Double) { | 280 | // BasePrice == 3000000.0; |
332 | find spacecraftWithTwoCommSubsystems(Spacecraft); | 281 | //} |
333 | Cost == 100000.0; | 282 | // |
334 | } or { | 283 | //private pattern interferometryPayloadCost(Spacecraft : Spacecraft, Cost : java Double) { |
335 | neg find spacecraftWithTwoCommSubsystems(Spacecraft); | 284 | // find spacecraftWithInterferometryPayload(_, Spacecraft); |
336 | Cost == 0.0; | 285 | // Cost == 50000.0; |
337 | } | 286 | //} or { |
338 | 287 | // neg find spacecraftWithInterferometryPayload(_, Spacecraft); | |
339 | private pattern spacecraftWithTwoCommSubsystems(Spacecraft : Spacecraft) { | 288 | // Cost == 0.0; |
340 | Spacecraft.commSubsystem(Spacecraft, Subsystem1); | 289 | //} |
341 | Spacecraft.commSubsystem(Spacecraft, Subsystem2); | 290 | // |
342 | Subsystem1 != Subsystem2; | 291 | //private pattern additionalCommSubsystemCost(Spacecraft : Spacecraft, Cost : java Double) { |
343 | } | 292 | // find spacecraftWithTwoCommSubsystems(Spacecraft); |
293 | // Cost == 100000.0; | ||
294 | //} or { | ||
295 | // neg find spacecraftWithTwoCommSubsystems(Spacecraft); | ||
296 | // Cost == 0.0; | ||
297 | //} | ||
298 | // | ||
299 | //private pattern spacecraftWithTwoCommSubsystems(Spacecraft : Spacecraft) { | ||
300 | // Spacecraft.commSubsystem(Spacecraft, Subsystem1); | ||
301 | // Spacecraft.commSubsystem(Spacecraft, Subsystem2); | ||
302 | // Subsystem1 != Subsystem2; | ||
303 | //} \ No newline at end of file | ||
diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/runner/SatelliteGeneratorMain.xtend b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/runner/SatelliteGeneratorMain.xtend index 592348e8..3d2cbbc7 100644 --- a/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/runner/SatelliteGeneratorMain.xtend +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.satellite/src/hu/bme/mit/inf/dslreasoner/domains/satellite/runner/SatelliteGeneratorMain.xtend | |||
@@ -6,8 +6,8 @@ final class SatelliteGeneratorMain { | |||
6 | private new() { | 6 | private new() { |
7 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly.") | 7 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly.") |
8 | } | 8 | } |
9 | 9 | ||
10 | static def void main(String[] args) { | 10 | public static def void main(String[] args) { |
11 | println(StandaloneScriptExecutor.executeScript("configs/generation.vsconfig")) | 11 | println(StandaloneScriptExecutor.executeScript("configs/generation.vsconfig")) |
12 | } | 12 | } |
13 | } | 13 | } |