Skip to content

Commit 56ec5ea

Browse files
committed
NAC codegeneration
1 parent 00a9af2 commit 56ec5ea

File tree

10 files changed

+198
-117
lines changed

10 files changed

+198
-117
lines changed

plugins/hu.bme.mit.incquery.localsearch.cpp/src/hu/bme/mit/incquery/localsearch/cpp/generator/internal/runtime/RuntimeQuerySpecificationGenerator.xtend

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class RuntimeQuerySpecificationGenerator extends QuerySpecificationGenerator {
4242
::Viatra::Query::Plan::SearchPlan<«frame.frameName»> sp;
4343
«val setupCode = new StringBuilder»
4444
«val opCodes = searchOperations.get(pattern).get(patternBody).map[compile(setupCode)]»
45+
««« evaluate so setup code gets calculated
46+
«opCodes.forEach[]»
4547

4648
«setupCode.toString»
4749

plugins/hu.bme.mit.incquery.localsearch.cpp/src/hu/bme/mit/incquery/localsearch/cpp/generator/internal/runtime/RuntimeSearchOperationGenerator.xtend

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import hu.bme.mit.incquery.localsearch.cpp.generator.model.CheckSingleNavigation
88
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ExtendInstanceOfStub
99
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ExtendMultiNavigationStub
1010
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ExtendSingleNavigationStub
11+
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ISearchOperationStub
12+
import hu.bme.mit.incquery.localsearch.cpp.generator.model.NACOperationStub
1113
import org.eclipse.emf.ecore.EClass
1214
import org.eclipse.emf.ecore.EClassifier
1315
import org.eclipse.emf.ecore.EStructuralFeature
1416
import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable
1517
import org.eclipse.xtend.lib.annotations.Accessors
16-
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ISearchOperationStub
17-
import hu.bme.mit.incquery.localsearch.cpp.generator.model.CheckNACOperationStub
1818

1919
class RuntimeSearchOperationGenerator extends BaseGenerator {
2020

@@ -51,9 +51,9 @@ class RuntimeSearchOperationGenerator extends BaseGenerator {
5151
return '''create_«CheckMultiNavigationStub::NAME»(«operation.source.toGetter», «operation.target.toGetter», «sourceType.toNavigator(operation.key.toRelationName)»)'''
5252
}
5353

54-
private dispatch def compileOperation(CheckNACOperationStub operation, StringBuilder setupCode) {
54+
private dispatch def compileOperation(NACOperationStub operation, StringBuilder setupCode) {
5555
setupCode.append('''«operation.matcher» matcher_«operation.hashCode»(model, «queryName»QueryGroup::instance()->context())''')
56-
return '''create_«CheckNACOperationStub::NAME»<«frameGenerator.frameName»>(matcher_«operation.hashCode», «operation.bindings.join(", ")»)'''
56+
return '''create_«NACOperationStub::NAME»<«frameGenerator.frameName»>(matcher_«operation.hashCode», «operation.bindings.join(", ")»)'''
5757
}
5858

5959
private dispatch def compileOperation(ExtendInstanceOfStub operation, StringBuilder setupCode) {

plugins/hu.bme.mit.incquery.localsearch.cpp/src/hu/bme/mit/incquery/localsearch/cpp/generator/model/ISearchOperationStub.xtend

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package hu.bme.mit.incquery.localsearch.cpp.generator.model
22

3-
import java.util.List
43
import java.util.Set
54
import org.eclipse.emf.ecore.EClassifier
65
import org.eclipse.emf.ecore.EStructuralFeature
@@ -63,12 +62,12 @@ abstract class AbstractSearchOperationStub implements ISearchOperationStub{
6362

6463
}
6564

66-
@Data class CheckNACOperationStub extends MultiNavigationStub {
65+
@Data class NACOperationStub extends AbstractSearchOperationStub {
6766

6867
public static val String NAME = "NACOperation"
6968

7069
val CharSequence matcher
71-
val List<PVariable> bindings
70+
val Set<PVariable> bindings
7271

7372
}
7473

plugins/hu.bme.mit.incquery.localsearch.cpp/src/hu/bme/mit/incquery/localsearch/cpp/generator/model/MatchingFrameStub.xtend

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class MatchingFrameStub {
5959
}
6060

6161
def getAllTypes() {
62-
ImmutableList::copyOf(variableInfoMap.values.map[type])
62+
ImmutableList::copyOf(variableInfoMap.values.map[type].filterNull)
6363
}
6464
}
6565

plugins/hu.bme.mit.incquery.localsearch.cpp/src/hu/bme/mit/incquery/localsearch/cpp/generator/planner/CPPSearchOperationAcceptor.xtend

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,59 @@ package hu.bme.mit.incquery.localsearch.cpp.generator.planner
22

33
import com.google.common.base.Optional
44
import com.google.common.collect.Maps
5+
import hu.bme.mit.incquery.localsearch.cpp.generator.model.CheckInstanceOfStub
6+
import hu.bme.mit.incquery.localsearch.cpp.generator.model.CheckMultiNavigationStub
7+
import hu.bme.mit.incquery.localsearch.cpp.generator.model.CheckSingleNavigationStub
8+
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ExtendInstanceOfStub
9+
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ExtendMultiNavigationStub
10+
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ExtendSingleNavigationStub
11+
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ISearchOperationStub
512
import hu.bme.mit.incquery.localsearch.cpp.generator.model.MatchingFrameStub
13+
import hu.bme.mit.incquery.localsearch.cpp.generator.model.NACOperationStub
614
import hu.bme.mit.incquery.localsearch.cpp.generator.model.PatternBodyStub
7-
import hu.bme.mit.incquery.localsearch.cpp.generator.model.SearchOperationStub
815
import hu.bme.mit.incquery.localsearch.cpp.generator.model.TypeInfo
916
import hu.bme.mit.incquery.localsearch.cpp.generator.model.VariableInfo
1017
import hu.bme.mit.incquery.localsearch.cpp.generator.planner.util.CompilerHelper
1118
import java.util.List
1219
import java.util.Map
1320
import java.util.Set
21+
import org.eclipse.emf.ecore.EReference
22+
import org.eclipse.emf.ecore.EStructuralFeature
23+
import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey
1424
import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey
1525
import org.eclipse.viatra.query.runtime.matchers.context.IInputKey
1626
import org.eclipse.viatra.query.runtime.matchers.planning.SubPlan
1727
import org.eclipse.viatra.query.runtime.matchers.psystem.PBody
1828
import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
1929
import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable
20-
import hu.bme.mit.incquery.localsearch.cpp.generator.model.CheckSingleNavigationStub
21-
import hu.bme.mit.incquery.localsearch.cpp.generator.model.CheckMultiNavigationStub
22-
import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey
23-
import hu.bme.mit.incquery.localsearch.cpp.generator.model.CheckInstanceOfStub
24-
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ExtendInstanceOfStub
25-
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ExtendSingleNavigationStub
26-
import hu.bme.mit.incquery.localsearch.cpp.generator.model.ExtendMultiNavigationStub
27-
import org.eclipse.emf.ecore.EStructuralFeature
28-
import org.eclipse.emf.ecore.EReference
30+
import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
31+
import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter
2932

3033
class CPPSearchOperationAcceptor implements ISearchOperationAcceptor {
3134

3235
val MatchingFrameRegistry matchingFrameRegistry
33-
val List<SearchOperationStub> searchOperations
36+
val List<ISearchOperationStub> searchOperations
37+
val List<MatcherReference> dependencies
38+
val int id
3439

3540
var Map<PVariable, TypeInfo> typeMapping
3641
var Map<PVariable, Integer> variableMapping
3742
var PBody pBody
38-
var MatchingFrameStub matchingFrame
43+
var MatchingFrameStub matchingFrame
3944

4045

41-
new (MatchingFrameRegistry frameRegistry) {
46+
new (int id, MatchingFrameRegistry frameRegistry) {
4247
this.matchingFrameRegistry = frameRegistry
4348
this.searchOperations = newArrayList
49+
this.dependencies = newArrayList
50+
this.id = id
4451
}
4552

4653
override initialize(SubPlan plan, Map<PVariable, Integer> variableMapping, Map<PConstraint, Set<Integer>> variableBindings) {
4754
this.typeMapping = CompilerHelper::createTypeMapping(plan)
4855
this.variableMapping = variableMapping
4956
this.pBody = plan.body
50-
this.matchingFrame = getMatchingFrame(pBody)
57+
this.matchingFrame = getMatchingFrame(pBody)
5158
}
5259

5360
override acceptContainmentCheck(PVariable sourceVariable, PVariable targetVariable, IInputKey inputKey) {
@@ -91,21 +98,38 @@ class CPPSearchOperationAcceptor implements ISearchOperationAcceptor {
9198

9299
searchOperations += new ExtendInstanceOfStub(matchingFrame, location, eClass)
93100
}
94-
101+
102+
override acceptNACOperation(PQuery calledPQuery, Set<PVariable> boundVariables, Set<PParameter> boundParameters) {
103+
val matcherName = '''«calledPQuery.fullyQualifiedName.substring(calledPQuery.fullyQualifiedName.lastIndexOf('.')+1).toFirstUpper»Matcher'''
104+
searchOperations += new NACOperationStub(matchingFrame, matcherName, boundVariables)
105+
106+
107+
108+
dependencies += new MatcherReference(calledPQuery, boundParameters)
109+
}
110+
95111
def getPatternBodyStub() {
96-
return new PatternBodyStub(pBody, matchingFrame, searchOperations);
112+
return new PatternBodyStub(pBody, id, matchingFrame, searchOperations);
113+
}
114+
115+
def getDependencies() {
116+
return dependencies.unmodifiableView
97117
}
98118

99119
private def getMatchingFrame(PBody pBody) {
100120
matchingFrameRegistry.getMatchingFrame(pBody).or[
101121
val variableToParameterMap = Maps::uniqueIndex(pBody.pattern.parameters) [pBody.getVariableByNameChecked(it.name)]
102122
// don't pass this to anything else or evaluate it! (Lazy evaluation!!)
103123
val variableInfos = pBody.uniqueVariables.map[
104-
new VariableInfo(Optional::fromNullable(variableToParameterMap.get(it)), it, typeMapping.get(it), variableMapping.get(it))
105-
].toList
124+
val type = typeMapping.get(it)
125+
if(type == null)
126+
return null
127+
return new VariableInfo(Optional::fromNullable(variableToParameterMap.get(it)), it, type, variableMapping.get(it))
128+
].filterNull.toList
106129
val frame = new MatchingFrameStub(variableInfos)
107130
matchingFrameRegistry.putMatchingFrame(pBody, frame)
108131
return frame
109132
]
110-
}
133+
}
134+
111135
}

plugins/hu.bme.mit.incquery.localsearch.cpp/src/hu/bme/mit/incquery/localsearch/cpp/generator/planner/ISearchOperationAcceptor.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import org.eclipse.viatra.query.runtime.matchers.planning.SubPlan;
88
import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint;
99
import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable;
10+
import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter;
11+
import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery;
1012

1113
public interface ISearchOperationAcceptor {
1214

@@ -18,4 +20,5 @@ public interface ISearchOperationAcceptor {
1820
public void acceptIterateOverClassInstances(PVariable location, IInputKey inputKey);
1921
public void acceptExtendToAssociationSource(PVariable sourceVariable, PVariable targetVariable, IInputKey inputKey);
2022
public void acceptExtendToAssociationTarget(PVariable sourceVariable, PVariable targetVariable, IInputKey inputKey);
23+
public void acceptNACOperation(PQuery calledPQuery, Set<PVariable> boundVariables, Set<PParameter> boundParameters);
2124
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package hu.bme.mit.incquery.localsearch.cpp.generator.planner
2+
3+
import java.util.Set
4+
import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter
5+
import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
6+
import org.eclipse.xtend.lib.annotations.Data
7+
8+
@Data
9+
class MatcherReference {
10+
PQuery referredQuery
11+
Set<PParameter> adornment
12+
}

plugins/hu.bme.mit.incquery.localsearch.cpp/src/hu/bme/mit/incquery/localsearch/cpp/generator/planner/POperationCompilerExperimental.xtend

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,27 @@ class POperationCompilerExperimental {
7373
}
7474
}
7575

76+
def dispatch createCheck(NegativePatternCall negativePatternCall, ISearchOperationAcceptor acceptor) {
77+
val bindings = variableBindings.get(negativePatternCall)
78+
val adornment = negativePatternCall.actualParametersTuple.elements.filter(PVariable).filter[
79+
bindings.contains(variableMapping.get(it))
80+
].toSet
81+
82+
val keySize = negativePatternCall.actualParametersTuple.size
83+
84+
val params = negativePatternCall.referredQuery.parameters
85+
val boundParams = newHashSet
86+
87+
for(i : 0..<keySize) {
88+
val pVariable = negativePatternCall.actualParametersTuple.get(i) as PVariable
89+
if(bindings.contains(variableMapping.get(pVariable))) {
90+
boundParams += params.get(i)
91+
}
92+
}
93+
94+
acceptor.acceptNACOperation(negativePatternCall.referredQuery, adornment, boundParams)
95+
}
96+
7697
// def dispatch createCheck(CheckPConstraint constraint, Map<PVariable, Integer> variableMapping, String patternName) {
7798
// pattern.addSearchOperation(new CheckExpressionStub(matchingFrame, constraint.affectedVariables, constraint.expression))
7899
// }
@@ -121,7 +142,7 @@ class POperationCompilerExperimental {
121142
}
122143

123144
def dispatch createExtend(NegativePatternCall negativePatternCall, ISearchOperationAcceptor acceptor) {
124-
145+
throw new UnsupportedOperationException("Cannot extend through a negative pattern call");
125146
}
126147

127148
def dispatch createExtend(ExportedParameter constraint, ISearchOperationAcceptor acceptor) {
@@ -133,8 +154,13 @@ class POperationCompilerExperimental {
133154
}
134155

135156
private def allBound(PConstraint pConstraint) {
136-
return variableBindings.get(pConstraint).containsAll(pConstraint.affectedVariables.map [
137-
variableMapping.get(it)
138-
].toSet)
157+
switch (pConstraint) {
158+
NegativePatternCall: return true
159+
default: return variableBindings.get(pConstraint).containsAll(
160+
pConstraint.affectedVariables.map [
161+
variableMapping.get(it)
162+
].toSet
163+
)
164+
}
139165
}
140166
}

plugins/hu.bme.mit.incquery.localsearch.cpp/src/hu/bme/mit/incquery/localsearch/cpp/generator/planner/PlanCompiler.xtend

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,61 +4,78 @@ import com.google.common.collect.ImmutableSet
44
import com.google.common.collect.Iterables
55
import hu.bme.mit.incquery.localsearch.cpp.generator.model.PatternStub
66
import java.util.List
7+
import java.util.Map
78
import java.util.Set
89
import java.util.concurrent.atomic.AtomicInteger
910
import org.apache.log4j.Logger
1011
import org.eclipse.viatra.query.runtime.emf.EMFQueryMetaContext
1112
import org.eclipse.viatra.query.runtime.matchers.psystem.PBody
1213
import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation
1314
import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference
14-
import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PDisjunction
1515
import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter
1616
import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
1717
import org.eclipse.viatra.query.runtime.matchers.psystem.rewriters.DefaultFlattenCallPredicate
1818
import org.eclipse.viatra.query.runtime.matchers.psystem.rewriters.PBodyNormalizer
1919
import org.eclipse.viatra.query.runtime.matchers.psystem.rewriters.PQueryFlattener
20-
import java.util.Collection
2120

2221
class PlanCompiler {
2322

2423
val PQueryFlattener flattener
25-
val PBodyNormalizer normalizer
24+
val PBodyNormalizer normalizer
25+
val Map<PQuery, Set<String>> alreadyCompiled
26+
val Set<MatcherReference> dependencies
27+
val MatchingFrameRegistry frameRegistry
2628

2729
extension val CPPLocalSearchRuntimeBasedStrategy strategy
2830
extension val POperationCompilerExperimental compiler
2931

3032
new () {
3133
this.flattener = new PQueryFlattener(new DefaultFlattenCallPredicate)
3234
this.normalizer = new PBodyNormalizer(null, false)
35+
this.alreadyCompiled = newHashMap
36+
this.dependencies = newHashSet
37+
this.frameRegistry = new MatchingFrameRegistry
38+
3339

3440
this.strategy = new CPPLocalSearchRuntimeBasedStrategy(false)
3541
this.compiler = new POperationCompilerExperimental
3642
}
3743

3844
def compilePlan(PQuery pQuery) {
39-
val frameRegistry = new MatchingFrameRegistry
40-
41-
val flatDisjunction = flattener.rewrite(pQuery.disjunctBodies)
42-
val normalizedDisjunction = normalizer.rewrite(flatDisjunction)
45+
this.dependencies.clear
4346

44-
val normalizedBodies = normalizedDisjunction.bodies.toList
47+
val normalizedBodies = pQuery.flattenAndNormalize
4548

4649
val bindings = pQuery.allAnnotations.filter[name == "Bind"]
4750
val boundPatternStubs = bindings.map[ binding |
48-
val boundParameters = getBoundParameters(binding, pQuery)
51+
val boundParameters = getBoundParameters(binding, pQuery)
4952

5053
val bodies = normalizedBodies.compile(boundParameters, frameRegistry)
54+
alreadyCompiled.put(pQuery, boundParameters.map[name].toSet)
5155
return new PatternStub(pQuery, bodies, boundParameters)
5256
]
5357

54-
val bodies = if(normalizedDisjunction.sensibleWithoutBinding) {
55-
normalizedBodies.compile(#{}, frameRegistry)
56-
} else {
57-
#{}
58-
}
58+
val bodies = normalizedBodies.compile(#{}, frameRegistry)
5959
val unboundPatternStub = new PatternStub(pQuery, bodies)
60+
61+
val dependentPatternStubs = dependencies.filter[
62+
// if not already compiled
63+
!alreadyCompiled.get(it.referredQuery)?.equals(it.adornment.map[name].toSet)
64+
].map[
65+
val dependentNormalizedBodies = it.referredQuery.flattenAndNormalize
66+
val dependentBodies = dependentNormalizedBodies.compile(it.adornment, frameRegistry)
67+
return new PatternStub(it.referredQuery, dependentBodies, it.adornment)
68+
]
69+
6070
// copy to prevent lazy evaluation
61-
return ImmutableSet::copyOf(Iterables::concat(#[unboundPatternStub], boundPatternStubs))
71+
return ImmutableSet::copyOf(Iterables::concat(#[unboundPatternStub], boundPatternStubs, dependentPatternStubs))
72+
}
73+
74+
private def flattenAndNormalize(PQuery pQuery) {
75+
val flatDisjunction = flattener.rewrite(pQuery.disjunctBodies)
76+
val normalizedDisjunction = normalizer.rewrite(flatDisjunction)
77+
78+
return normalizedDisjunction.bodies.toList
6279
}
6380

6481
private def getBoundParameters(PAnnotation binding, PQuery pQuery) {
@@ -74,6 +91,7 @@ class PlanCompiler {
7491

7592
def compile(List<PBody> normalizedBodies, Iterable<PParameter> boundParameters, MatchingFrameRegistry frameRegistry) {
7693

94+
// no need for atomic, required a simple counter with final reference in closure
7795
val AtomicInteger counter = new AtomicInteger(0)
7896
val patternBodyStubs = normalizedBodies.map[pBody |
7997
val boundPVariables = boundParameters.map[pBody.getVariableByNameChecked(name)]
@@ -82,19 +100,10 @@ class PlanCompiler {
82100
val acceptor = new CPPSearchOperationAcceptor(counter.getAndIncrement, frameRegistry)
83101
pBody.plan(Logger::getLogger(PlanCompiler), boundPVariables, EMFQueryMetaContext.INSTANCE, null, #{})
84102
.compile(pBody, boundPVariables, acceptor)
85-
103+
dependencies += acceptor.dependencies
86104
return acceptor.patternBodyStub
87105
].toSet
88106

89107
return patternBodyStubs
90108
}
91-
92-
/**
93-
* Check if the provided disjunction is sensible without binding.
94-
*
95-
* A disjunction is sensible if all the unbound variables are deducable.
96-
*/
97-
def isSensibleWithoutBinding(PDisjunction disjunction) {
98-
disjunction.bodies.forall[allVariables.filter[unique].forall[deducable]]
99-
}
100109
}

0 commit comments

Comments
 (0)