Refactor constraint occurrence to depend on controller directly.
Drop creating of a frame stack from a store view.
This commit is contained in:
parent
b482de1ce5
commit
bfc4b641bb
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package jetbrains.mps.logic.reactor.core
|
||||
|
||||
import jetbrains.mps.logic.reactor.evaluation.PredicateInvocation
|
||||
import jetbrains.mps.logic.reactor.evaluation.StoreView
|
||||
|
||||
/**
|
||||
|
|
@ -25,8 +26,14 @@ import jetbrains.mps.logic.reactor.evaluation.StoreView
|
|||
*/
|
||||
interface Controller {
|
||||
|
||||
fun ask(invocation: PredicateInvocation): Boolean
|
||||
|
||||
fun tell(invocation: PredicateInvocation)
|
||||
|
||||
fun reactivate(occ: Occurrence)
|
||||
|
||||
fun currentFrame(): FrameObservable
|
||||
|
||||
/** For tests only */
|
||||
fun evaluate(occ: Occurrence): StoreView
|
||||
|
||||
|
|
|
|||
|
|
@ -41,17 +41,10 @@ abstract class EvaluationSessionEx(val program: Program,
|
|||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : Any> parameter(key: ParameterKey<T>): T? = params ?.get(key) as T
|
||||
|
||||
override fun ask(invocation: PredicateInvocation): Boolean {
|
||||
val solver = invocation.predicate().symbol().solver()
|
||||
val result = solver.ask(invocation)
|
||||
trace.ask(result, invocation)
|
||||
return result
|
||||
}
|
||||
override fun ask(invocation: PredicateInvocation): Boolean =
|
||||
controller().ask(invocation)
|
||||
|
||||
override fun tell(invocation: PredicateInvocation) {
|
||||
val solver = invocation.predicate().symbol().solver()
|
||||
trace.tell(invocation)
|
||||
solver.tell(invocation)
|
||||
}
|
||||
override fun tell(invocation: PredicateInvocation) =
|
||||
controller().tell(invocation)
|
||||
|
||||
}
|
||||
|
|
@ -18,8 +18,6 @@ package jetbrains.mps.logic.reactor.core
|
|||
|
||||
import jetbrains.mps.logic.reactor.evaluation.ConstraintOccurrence
|
||||
|
||||
import jetbrains.mps.logic.reactor.evaluation.EvaluationSession
|
||||
|
||||
import jetbrains.mps.logic.reactor.logical.Logical
|
||||
import jetbrains.mps.logic.reactor.logical.LogicalContext
|
||||
import jetbrains.mps.logic.reactor.logical.MetaLogical
|
||||
|
|
@ -30,10 +28,10 @@ import jetbrains.mps.logic.reactor.program.Constraint
|
|||
*
|
||||
* @author Fedor Isakov
|
||||
*/
|
||||
data class Occurrence (val constraint: Constraint,
|
||||
data class Occurrence (val controller: Controller,
|
||||
val constraint: Constraint,
|
||||
val logicalContext: LogicalContext,
|
||||
val arguments: List<*>,
|
||||
val currentFrame: () -> FrameObservable) :
|
||||
val arguments: List<*>) :
|
||||
ConstraintOccurrence,
|
||||
LogicalObserver
|
||||
{
|
||||
|
|
@ -45,7 +43,7 @@ data class Occurrence (val constraint: Constraint,
|
|||
init {
|
||||
for (a in arguments) {
|
||||
if (a is Logical<*>) {
|
||||
currentFrame().addObserver(a) { this }
|
||||
controller.currentFrame().addObserver(a) { this }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -58,20 +56,20 @@ data class Occurrence (val constraint: Constraint,
|
|||
|
||||
override fun valueUpdated(logical: Logical<*>) {
|
||||
if (alive) {
|
||||
EvaluationSession.current(EvaluationSessionEx::class.java).controller().reactivate(this)
|
||||
controller.reactivate(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun parentUpdated(logical: Logical<*>) {
|
||||
if (alive) {
|
||||
EvaluationSession.current(EvaluationSessionEx::class.java).controller().reactivate(this)
|
||||
controller.reactivate(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun terminate() {
|
||||
for (a in arguments) {
|
||||
if (a is Logical<*>) {
|
||||
currentFrame().removeObserver(a) { this }
|
||||
controller.currentFrame().removeObserver(a) { this }
|
||||
}
|
||||
}
|
||||
alive = false
|
||||
|
|
@ -81,14 +79,14 @@ data class Occurrence (val constraint: Constraint,
|
|||
|
||||
}
|
||||
|
||||
fun Constraint.occurrence(arguments: List<*>,
|
||||
currentFrame: () -> FrameObservable,
|
||||
logicalContext: LogicalContext): Occurrence =
|
||||
Occurrence(this, logicalContext, arguments, currentFrame)
|
||||
fun Constraint.occurrence(controller: Controller,
|
||||
arguments: List<*>,
|
||||
logicalContext: LogicalContext): Occurrence =
|
||||
Occurrence(controller, this, logicalContext, arguments)
|
||||
|
||||
fun Constraint.occurrence(arguments: List<*>,
|
||||
currentFrame: () -> FrameObservable): Occurrence =
|
||||
Occurrence(this, noLogicalContext, arguments, currentFrame)
|
||||
fun Constraint.occurrence(controller: Controller,
|
||||
arguments: List<*>): Occurrence =
|
||||
Occurrence(controller, this, noLogicalContext, arguments)
|
||||
|
||||
private val noLogicalContext: LogicalContext = object: LogicalContext {
|
||||
override fun <V : Any> variable(metaLogical: MetaLogical<V>): Logical<V>? = null
|
||||
|
|
|
|||
|
|
@ -32,18 +32,13 @@ internal class ControllerImpl (
|
|||
val supervisor: Supervisor,
|
||||
val ruleIndex: RuleIndex,
|
||||
val trace: EvaluationTrace = EvaluationTrace.NULL,
|
||||
val profiler: Profiler? = null,
|
||||
val storeView: StoreView? = null) : Controller
|
||||
val profiler: Profiler? = null) : Controller
|
||||
{
|
||||
|
||||
// FIXME move to parameter
|
||||
private val session: EvaluationSession = EvaluationSession.current()
|
||||
|
||||
|
||||
private var dispatchFront = Dispatcher(ruleIndex).front()
|
||||
|
||||
// FIXME move to context
|
||||
private val frameStack = FrameStack(storeView)
|
||||
private val frameStack = FrameStack()
|
||||
|
||||
/** For tests only */
|
||||
override fun storeView(): StoreView = frameStack.current.store.view()
|
||||
|
|
@ -51,7 +46,7 @@ internal class ControllerImpl (
|
|||
/** For tests only */
|
||||
override fun evaluate(occ: Occurrence): StoreView {
|
||||
// create the internal occurrence
|
||||
val active = occ.constraint().occurrence(occ.arguments(), { frameStack.current })
|
||||
val active = occ.constraint().occurrence(this, occ.arguments())
|
||||
val status = process(active, NORMAL())
|
||||
if (status is FAILED) {
|
||||
throw status.failure.failureCause()
|
||||
|
|
@ -66,6 +61,21 @@ internal class ControllerImpl (
|
|||
return context.currentStatus()
|
||||
}
|
||||
|
||||
override fun currentFrame(): FrameObservable = frameStack.current
|
||||
|
||||
override fun ask(invocation: PredicateInvocation): Boolean {
|
||||
val solver = invocation.predicate().symbol().solver()
|
||||
val result = solver.ask(invocation)
|
||||
trace.ask(result, invocation)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun tell(invocation: PredicateInvocation) {
|
||||
val solver = invocation.predicate().symbol().solver()
|
||||
trace.tell(invocation)
|
||||
solver.tell(invocation)
|
||||
}
|
||||
|
||||
override fun reactivate(occ: Occurrence) {
|
||||
// FIXME propagate the status further up the call stack
|
||||
// TODO: introduce status to solver API?
|
||||
|
|
@ -148,6 +158,14 @@ internal class ControllerImpl (
|
|||
trace.discard(occ)
|
||||
}
|
||||
|
||||
processBody(match, context)
|
||||
|
||||
trace.finish(match)
|
||||
|
||||
return context.currentStatus()
|
||||
}
|
||||
|
||||
private fun processBody(match: RuleMatchImpl, context: Context) {
|
||||
val altIt = match.rule().bodyAlternation().iterator()
|
||||
while (altIt.hasNext()) {
|
||||
val body = altIt.next()
|
||||
|
|
@ -216,16 +234,12 @@ internal class ControllerImpl (
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
trace.finish(match)
|
||||
|
||||
return context.currentStatus()
|
||||
}
|
||||
|
||||
private fun activateConstraint(constraint: Constraint, context: Context) : Boolean {
|
||||
val args = supervisor.instantiateArguments(constraint.arguments(), context.logicalContext, context)
|
||||
return context.updateStatus { status ->
|
||||
val active = constraint.occurrence(args, { frameStack.current }, context.logicalContext)
|
||||
val active = constraint.occurrence(this, args, context.logicalContext)
|
||||
process(active, status)
|
||||
}
|
||||
}
|
||||
|
|
@ -235,7 +249,7 @@ internal class ControllerImpl (
|
|||
|
||||
context.evalSafe { status ->
|
||||
val args = supervisor.instantiateArguments(predicate.arguments(), context.logicalContext, context)
|
||||
if (session.ask(predicate.invocation(args, context.logicalContext, context)))
|
||||
if (ask(predicate.invocation(args, context.logicalContext, context)))
|
||||
status
|
||||
else
|
||||
status.abort(DetailedFeedback("predicate not satisfied"))
|
||||
|
|
@ -248,7 +262,7 @@ internal class ControllerImpl (
|
|||
|
||||
context.runSafe {
|
||||
val args = supervisor.instantiateArguments(predicate.arguments(), context.logicalContext, context)
|
||||
session.tell(predicate.invocation(args, context.logicalContext, context))
|
||||
tell(predicate.invocation(args, context.logicalContext, context))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -264,54 +278,54 @@ internal class ControllerImpl (
|
|||
|
||||
private fun RuleMatch.allStored() = (matchHeadKept() + matchHeadReplaced()).all { co -> (co as Occurrence).stored }
|
||||
|
||||
}
|
||||
private class Context(inStatus: FeedbackStatus,
|
||||
val logicalContext: LogicalContext) : InvocationContext
|
||||
{
|
||||
|
||||
private class Context(inStatus: FeedbackStatus,
|
||||
val logicalContext: LogicalContext) : InvocationContext
|
||||
{
|
||||
private var status = inStatus
|
||||
fun currentStatus(): FeedbackStatus = status
|
||||
|
||||
private var status = inStatus
|
||||
fun currentStatus(): FeedbackStatus = status
|
||||
|
||||
override fun report(feedback: EvaluationFeedback) {
|
||||
when (feedback) {
|
||||
is EvaluationFailure -> this.status = status.fail(feedback)
|
||||
is DetailedFeedback -> this.status = status.report(feedback)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun withStatus(block: (FeedbackStatus) -> Unit) {
|
||||
block.invoke(status)
|
||||
}
|
||||
|
||||
inline fun updateStatus(block: (FeedbackStatus) -> FeedbackStatus) : Boolean {
|
||||
this.status = block.invoke(status)
|
||||
return status.operational
|
||||
}
|
||||
|
||||
inline fun evalSafe(block: (FeedbackStatus) -> FeedbackStatus) : Boolean {
|
||||
if (status.operational) {
|
||||
try {
|
||||
this.status = block.invoke(status)
|
||||
|
||||
} catch (ex: EvaluationFailureException) {
|
||||
this.status = status.fail(EvaluationFailure(ex))
|
||||
}
|
||||
}
|
||||
return status.operational
|
||||
}
|
||||
|
||||
inline fun runSafe(block: () -> Unit) : Boolean {
|
||||
if (status.operational) {
|
||||
try {
|
||||
block()
|
||||
|
||||
} catch (ex: EvaluationFailureException) {
|
||||
this.status = status.fail(EvaluationFailure(ex))
|
||||
override fun report(feedback: EvaluationFeedback) {
|
||||
when (feedback) {
|
||||
is EvaluationFailure -> this.status = status.fail(feedback)
|
||||
is DetailedFeedback -> this.status = status.report(feedback)
|
||||
}
|
||||
}
|
||||
|
||||
return status.operational
|
||||
inline fun withStatus(block: (FeedbackStatus) -> Unit) {
|
||||
block.invoke(status)
|
||||
}
|
||||
|
||||
inline fun updateStatus(block: (FeedbackStatus) -> FeedbackStatus) : Boolean {
|
||||
this.status = block.invoke(status)
|
||||
return status.operational
|
||||
}
|
||||
|
||||
inline fun evalSafe(block: (FeedbackStatus) -> FeedbackStatus) : Boolean {
|
||||
if (status.operational) {
|
||||
try {
|
||||
this.status = block.invoke(status)
|
||||
|
||||
} catch (ex: EvaluationFailureException) {
|
||||
this.status = status.fail(EvaluationFailure(ex))
|
||||
}
|
||||
}
|
||||
return status.operational
|
||||
}
|
||||
|
||||
inline fun runSafe(block: () -> Unit) : Boolean {
|
||||
if (status.operational) {
|
||||
try {
|
||||
block()
|
||||
|
||||
} catch (ex: EvaluationFailureException) {
|
||||
this.status = status.fail(EvaluationFailure(ex))
|
||||
}
|
||||
}
|
||||
|
||||
return status.operational
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -323,4 +337,4 @@ fun createController(
|
|||
trace: EvaluationTrace = EvaluationTrace.NULL,
|
||||
profiler: Profiler? = null,
|
||||
storeView: StoreView? = null) : Controller =
|
||||
ControllerImpl(supervisor, ruleIndex, trace, profiler, storeView)
|
||||
ControllerImpl(supervisor, ruleIndex, trace, profiler)
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ internal class EvaluationSessionImpl private constructor (
|
|||
|
||||
override fun controller() = controller
|
||||
|
||||
private fun launch(main: Constraint, profiler: Profiler?, storeView: StoreView?) : FeedbackStatus {
|
||||
this.controller = ControllerImpl(supervisor, RuleIndex(program().handlers()), trace, profiler, storeView)
|
||||
private fun launch(main: Constraint, profiler: Profiler?) : FeedbackStatus {
|
||||
this.controller = ControllerImpl(supervisor, RuleIndex(program().handlers()), trace, profiler)
|
||||
return controller.activate(main)
|
||||
}
|
||||
|
||||
|
|
@ -54,15 +54,12 @@ internal class EvaluationSessionImpl private constructor (
|
|||
|
||||
var evaluationTrace: EvaluationTrace = EvaluationTrace.NULL
|
||||
|
||||
var storeView: StoreView? = null
|
||||
|
||||
override fun withTrace(computingTracer: EvaluationTrace): EvaluationSession.Config {
|
||||
this.evaluationTrace = computingTracer
|
||||
return this
|
||||
}
|
||||
|
||||
override fun withStoreView(storeView: StoreView): EvaluationSession.Config {
|
||||
this.storeView = storeView
|
||||
return this
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +82,7 @@ internal class EvaluationSessionImpl private constructor (
|
|||
var failure: Feedback? = null
|
||||
try {
|
||||
val main = parameters[ParameterKey.of("main", Constraint::class.java)] as Constraint
|
||||
val status = session.launch(main, profiler, storeView)
|
||||
val status = session.launch(main, profiler)
|
||||
if (status is FAILED) {
|
||||
failure = status.failure
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,12 +49,6 @@ internal class Frame: LogicalObserver, FrameObservable {
|
|||
this.observers = prev.observers
|
||||
}
|
||||
|
||||
constructor(stack: FrameStack, storeView: StoreView) {
|
||||
this.stack = stack
|
||||
this.store = Store(storeView) { stack.current }
|
||||
this.observers = Maps.of()
|
||||
}
|
||||
|
||||
override fun storeObserver() = store
|
||||
|
||||
override fun addObserver(logical: Logical<*>, obs: (FrameObservable) -> LogicalObserver) {
|
||||
|
|
@ -94,14 +88,14 @@ internal class Frame: LogicalObserver, FrameObservable {
|
|||
|
||||
}
|
||||
|
||||
internal class FrameStack(storeView: StoreView?) : LogicalObserver {
|
||||
internal class FrameStack : LogicalObserver {
|
||||
|
||||
var current: Frame
|
||||
|
||||
val observing = HashSet<Id<Logical<*>>>()
|
||||
|
||||
init {
|
||||
this.current = if (storeView != null) Frame(this, storeView) else Frame(this)
|
||||
this.current = Frame(this)
|
||||
}
|
||||
|
||||
fun push(): Frame {
|
||||
|
|
|
|||
|
|
@ -53,43 +53,7 @@ internal class Store : LogicalObserver {
|
|||
this.symbol2occurrences = copyFrom.symbol2occurrences
|
||||
this.logical2occurrences = copyFrom.logical2occurrences
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy constructor that accepts a view on the store.
|
||||
* This can be a view on the store from previous run of the program.
|
||||
*/
|
||||
constructor(copyFrom: StoreView, currentFrame: () -> FrameObservable) {
|
||||
this.currentFrame = currentFrame
|
||||
|
||||
var log2occs = Maps.of<Id<Logical<*>>, IdHashSet<Occurrence>>()
|
||||
val orig2occ = IdentityHashMap<ConstraintOccurrence, Occurrence>()
|
||||
|
||||
// process the original data and make copies as needed
|
||||
for (orig in copyFrom.allOccurrences()) {
|
||||
val occ = orig.constraint().occurrence(orig.arguments(), currentFrame)
|
||||
orig2occ[orig] = occ
|
||||
for (arg in orig.arguments()) {
|
||||
when (arg) {
|
||||
is Logical<*> -> {
|
||||
val key = Id(arg.findRoot())
|
||||
log2occs = log2occs.put(key,
|
||||
log2occs[key]?.add(occ) ?: singletonIdSet(occ))
|
||||
currentFrame().addObserver(arg) { frame -> frame.storeObserver() }
|
||||
}
|
||||
}
|
||||
}
|
||||
occ.stored = true
|
||||
}
|
||||
|
||||
// set internal structures
|
||||
this.logical2occurrences = log2occs
|
||||
this.symbol2occurrences = copyFrom.constraintSymbols().fold(Maps.of()) { pmap, csym ->
|
||||
val occs = IdHashSet(copyFrom.occurrences(csym).map { occ -> orig2occ.get(occ)!! })
|
||||
pmap.put(csym, occs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
constructor(currentFrame: () -> FrameObservable) {
|
||||
this.currentFrame = currentFrame
|
||||
this.symbol2occurrences = Maps.of()
|
||||
|
|
|
|||
|
|
@ -88,6 +88,10 @@ public abstract class EvaluationSession {
|
|||
|
||||
public abstract Config withTrace(EvaluationTrace computingTracer);
|
||||
|
||||
/**
|
||||
* @deprecated passing store view is deprecated and doesn't have an effect
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract Config withStoreView(StoreView storeView);
|
||||
|
||||
public abstract EvaluationResult start(Supervisor supervisor);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import jetbrains.mps.logic.reactor.core.*
|
||||
import jetbrains.mps.logic.reactor.evaluation.PredicateInvocation
|
||||
import jetbrains.mps.logic.reactor.evaluation.StoreView
|
||||
import jetbrains.mps.logic.reactor.logical.Logical
|
||||
import jetbrains.mps.logic.reactor.program.*
|
||||
import program.MockConstraint
|
||||
|
|
@ -112,7 +114,7 @@ fun equals(left: Any, right: Any): ConjBuilder.() -> Unit = {
|
|||
}
|
||||
|
||||
fun occurrence(id: String, vararg args: Any): Occurrence =
|
||||
MockConstraint(ConstraintSymbol.symbol(id, args.size)).occurrence(listOf(* args), { fooObservable })
|
||||
MockConstraint(ConstraintSymbol.symbol(id, args.size)).occurrence(MockController(), listOf(* args))
|
||||
|
||||
fun sym0(id: String): ConstraintSymbol =
|
||||
ConstraintSymbol(id, 0)
|
||||
|
|
@ -123,15 +125,38 @@ fun sym1(id: String): ConstraintSymbol =
|
|||
fun sym2(id: String): ConstraintSymbol =
|
||||
ConstraintSymbol(id, 2)
|
||||
|
||||
object fooObservable : FrameObservable {
|
||||
override fun storeObserver(): LogicalObserver {
|
||||
class MockController : Controller {
|
||||
|
||||
override fun currentFrame(): FrameObservable = object : FrameObservable {
|
||||
override fun storeObserver(): LogicalObserver {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun addObserver(logical: Logical<*>, obs: (FrameObservable) -> LogicalObserver) {
|
||||
}
|
||||
|
||||
override fun removeObserver(logical: Logical<*>, obs: (FrameObservable) -> LogicalObserver) {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
override fun ask(invocation: PredicateInvocation): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun addObserver(logical: Logical<*>, obs: (FrameObservable) -> LogicalObserver) {
|
||||
override fun tell(invocation: PredicateInvocation) {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun removeObserver(logical: Logical<*>, obs: (FrameObservable) -> LogicalObserver) {
|
||||
override fun reactivate(occ: Occurrence) {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun evaluate(occ: Occurrence): StoreView {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun storeView(): StoreView {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class TestController {
|
|||
private fun Builder.controller(vararg occurrences: ConstraintOccurrence): Controller {
|
||||
val program = MockProgram("test", rulesLists, registry = MockConstraintRegistry())
|
||||
MockSession.init(program, MockSupervisor())
|
||||
val controller = createController(MockSupervisor(), RuleIndex(program.rulesLists), storeView = MockStoreView(listOf(* occurrences)))
|
||||
val controller = createController(MockSupervisor(), RuleIndex(program.rulesLists))
|
||||
MockSession.ourBackend.session.controller = controller
|
||||
return controller
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ class TestController {
|
|||
feedbackHandler(rule, feedback)
|
||||
}
|
||||
MockSession.init(program, supervisor)
|
||||
val controller = createController(supervisor, RuleIndex(program.rulesLists), storeView = MockStoreView(listOf(* occurrences)))
|
||||
val controller = createController(supervisor, RuleIndex(program.rulesLists))
|
||||
MockSession.ourBackend.session.controller = controller
|
||||
return controller
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@ import jetbrains.mps.logic.reactor.evaluation.EvaluationSession
|
|||
import jetbrains.mps.logic.reactor.evaluation.StoreView
|
||||
import jetbrains.mps.logic.reactor.program.Constraint
|
||||
import jetbrains.mps.logic.reactor.program.ConstraintSymbol
|
||||
import org.junit.AfterClass
|
||||
import org.junit.Assert
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Test
|
||||
import org.junit.*
|
||||
import program.MockConstraint
|
||||
|
||||
/*
|
||||
|
|
@ -65,6 +62,7 @@ class TestIncrementalProgram {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
fun replace() {
|
||||
programWithRules(
|
||||
rule("main",
|
||||
|
|
|
|||
Loading…
Reference in New Issue