Handlers to have multiple primary constraints. RuleIndex to select handlers with matching primary symbol, if a handler has one. Only "accept-all" handlers process non-primary constraints.
This commit is contained in:
parent
26f12f187d
commit
466c015263
|
|
@ -7,7 +7,7 @@ public abstract class Handler {
|
|||
|
||||
public abstract String name();
|
||||
|
||||
public abstract ConstraintSymbol primarySymbol();
|
||||
public abstract Iterable<ConstraintSymbol> primarySymbols();
|
||||
|
||||
public abstract Iterable<Rule> rules();
|
||||
|
||||
|
|
|
|||
|
|
@ -33,35 +33,30 @@ class RuleIndex : Iterable<Rule> {
|
|||
|
||||
fun byTag(tag: String): Rule? = tag2rule[tag]
|
||||
|
||||
fun forOccurrence(occ: ConstraintOccurrence): Iterable<Rule> {
|
||||
val primary = primarySymbol2valueIndex.get(occ.constraint().symbol())?.select(occ) ?: emptyList()
|
||||
val all = allSymbol2valueIndex.get(occ.constraint().symbol())?.select(occ) ?: emptyList()
|
||||
return primary + all
|
||||
}
|
||||
fun forOccurrence(occ: ConstraintOccurrence): Iterable<Rule> =
|
||||
primarySymbol2valueIndex.get(occ.constraint().symbol())?.select(occ) ?:
|
||||
(allSymbol2valueIndex.get(occ.constraint().symbol())?.select(occ) ?: emptyList())
|
||||
|
||||
override fun iterator(): Iterator<Rule> = tag2rule.values.iterator()
|
||||
|
||||
private fun buildIndex(handlers: Iterable<Handler>) {
|
||||
// first, init the primary symbols value index
|
||||
handlers
|
||||
.flatMap { h -> h.primarySymbols() }
|
||||
.forEach { symbol -> primarySymbol2valueIndex.getOrPut(symbol) { ValueIndex(symbol) } }
|
||||
|
||||
for (h in handlers) {
|
||||
val primaryValueIdx = h.primarySymbol()?.let { symbol ->
|
||||
allSymbol2valueIndex.getOrPut(symbol) { ValueIndex(symbol) }
|
||||
}
|
||||
val hPrimSyms = h.primarySymbols().toSet()
|
||||
for (r in h.rules()) {
|
||||
for (c in r.headKept()) {
|
||||
if (c.symbol() == h.primarySymbol()) {
|
||||
primaryValueIdx?.update(r, c)
|
||||
|
||||
} else if (h.primarySymbol() == null) {
|
||||
allSymbol2valueIndex.getOrPut(c.symbol()) { ValueIndex(c.symbol()) }.update(r, c)
|
||||
for (c in (r.headKept() + r.headReplaced())) {
|
||||
val symbol = c.symbol()
|
||||
if (symbol in hPrimSyms) {
|
||||
primarySymbol2valueIndex[symbol]?.update(r, c)
|
||||
}
|
||||
}
|
||||
for (c in r.headReplaced()) {
|
||||
if (c.symbol() == h.primarySymbol()) {
|
||||
primaryValueIdx?.update(r, c)
|
||||
|
||||
} else if (h.primarySymbol() == null) {
|
||||
allSymbol2valueIndex.getOrPut(c.symbol()) { ValueIndex(c.symbol()) }.update(r, c)
|
||||
else if (hPrimSyms.isEmpty()) {
|
||||
allSymbol2valueIndex.getOrPut(symbol) { ValueIndex(symbol) }.update(r, c)
|
||||
}
|
||||
// else ignore the constraint -- it's not meant to be processed by this handler, as it is not a primary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class ProgramBuilder(val registry: ConstraintRegistry) {
|
|||
|
||||
}
|
||||
|
||||
open class HandlerBuilder(val name: String, val primary: ConstraintSymbol?) {
|
||||
open class HandlerBuilder(val name: String, val primary: Iterable<ConstraintSymbol>) {
|
||||
val rules = ArrayList<Rule>()
|
||||
|
||||
fun appendRule(rule: Rule) {
|
||||
|
|
@ -61,12 +61,12 @@ open class RuleBuilder(val tag: String) {
|
|||
|
||||
class MockHandler(
|
||||
val name: String,
|
||||
val primary: ConstraintSymbol?,
|
||||
val primary: Iterable<ConstraintSymbol>,
|
||||
val rules: List<Rule>) : Handler() {
|
||||
|
||||
override fun name(): String = name
|
||||
|
||||
override fun primarySymbol(): ConstraintSymbol? = primary
|
||||
override fun primarySymbols(): Iterable<ConstraintSymbol> = primary
|
||||
|
||||
override fun rules(): Iterable<Rule> = rules
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ fun programWithRules(pb: ProgramBuilder, vararg ruleBuilders : Environment.() ->
|
|||
}
|
||||
|
||||
private fun programWithRules(env: Environment, ruleBuilders: Array<out Environment.() -> Rule>): Builder {
|
||||
return builder(env, arrayOf(handler("test", null, * ruleBuilders)))
|
||||
return builder(env, arrayOf(handler("test", emptyList(), * ruleBuilders)))
|
||||
}
|
||||
|
||||
fun programWithHandlers(vararg handlerBuilders : Environment.() -> Handler): Builder {
|
||||
|
|
@ -51,7 +51,7 @@ private fun builder(env: Environment, handlerBlocks: Array<out Environment.() ->
|
|||
return Builder(env, handlers)
|
||||
}
|
||||
|
||||
fun handler(name: String, primary: ConstraintSymbol?, vararg ruleBlocks: Environment.() -> Rule): Environment.() -> Handler = {
|
||||
fun handler(name: String, primary: Iterable<ConstraintSymbol>, vararg ruleBlocks: Environment.() -> Rule): Environment.() -> Handler = {
|
||||
val hb = HandlerBuilder(name, primary)
|
||||
for (block in ruleBlocks) {
|
||||
hb.appendRule(this.block())
|
||||
|
|
|
|||
|
|
@ -184,13 +184,13 @@ class TestMatcher {
|
|||
@Test
|
||||
fun multipleHandlers() {
|
||||
programWithHandlers(
|
||||
handler("handler1", ConstraintSymbol("foo", 0),
|
||||
handler("handler1", listOf(ConstraintSymbol("foo", 0)),
|
||||
rule("main1",
|
||||
headKept(
|
||||
constraint("foo")
|
||||
))
|
||||
),
|
||||
handler("handler2", ConstraintSymbol("bar", 0),
|
||||
handler("handler2", listOf(ConstraintSymbol("bar", 0)),
|
||||
rule("main2",
|
||||
headKept(
|
||||
constraint("bar")
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class TestProgramBuilder {
|
|||
constraint("bar")
|
||||
))).run {
|
||||
|
||||
programBuilder.addHandler(MockHandler("test", null, rules))
|
||||
programBuilder.addHandler(MockHandler("test", emptyList(), rules))
|
||||
assertEquals(programBuilder.program("test").rules().count(), 1)
|
||||
assertEquals(programBuilder.program("test").rules().count(), 1)
|
||||
}
|
||||
|
|
@ -66,7 +66,7 @@ class TestProgramBuilder {
|
|||
constraint("blah")
|
||||
))).run {
|
||||
|
||||
programBuilder.addHandler(MockHandler("test", null, rules))
|
||||
programBuilder.addHandler(MockHandler("test", emptyList(), rules))
|
||||
assertEquals(programBuilder.program("test").rules().count(), 2)
|
||||
}
|
||||
}
|
||||
|
|
@ -82,7 +82,7 @@ class TestProgramBuilder {
|
|||
constraint("bar", "1")
|
||||
))).run {
|
||||
|
||||
programBuilder.addHandler(MockHandler("test", null, rules))
|
||||
programBuilder.addHandler(MockHandler("test", emptyList(), rules))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue