-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3ee1792
commit 4d1500f
Showing
3 changed files
with
114 additions
and
0 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
procedural/constraints/src/main/kotlin/gov/nasa/jpl/aerie/constraints/ActivityId.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package gov.nasa.jpl.aerie.constraints | ||
|
||
/** An activity ID, referencing either a directive or instance. */ | ||
sealed interface ActivityId { | ||
/***/ data class InstanceId(/***/ val id: Long): ActivityId | ||
/***/ data class DirectiveId(/***/ val id: Long): ActivityId | ||
} |
22 changes: 22 additions & 0 deletions
22
procedural/constraints/src/main/kotlin/gov/nasa/jpl/aerie/constraints/Violation.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package gov.nasa.jpl.aerie.constraints | ||
|
||
import gov.nasa.jpl.aerie.timeline.Interval | ||
import gov.nasa.jpl.aerie.timeline.payloads.IntervalLike | ||
|
||
/** A single violation of a constraint. */ | ||
data class Violation( | ||
/** Interval on which the violation occurs. */ | ||
override val interval: Interval, | ||
|
||
/** List of associated activities (directives or instances) that are related to the violation. */ | ||
val ids: List<ActivityId> = listOf() | ||
) : IntervalLike<Violation> { | ||
|
||
override fun withNewInterval(i: Interval) = Violation(i, ids) | ||
|
||
/** Constructs a violation on the same interval with a different list of ids. */ | ||
fun withNewIds(vararg id: ActivityId) = Violation(interval, id.asList()) | ||
|
||
/** Constructs a violation on the same interval with a different list of ids. */ | ||
fun withNewIds(ids: List<ActivityId>) = Violation(interval, ids) | ||
} |
85 changes: 85 additions & 0 deletions
85
procedural/constraints/src/main/kotlin/gov/nasa/jpl/aerie/constraints/Violations.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package gov.nasa.jpl.aerie.constraints | ||
|
||
import gov.nasa.jpl.aerie.constraints.ActivityId.DirectiveId | ||
import gov.nasa.jpl.aerie.constraints.ActivityId.InstanceId | ||
import gov.nasa.jpl.aerie.constraints.Violations.Companion.getActivityId | ||
import gov.nasa.jpl.aerie.timeline.BaseTimeline | ||
import gov.nasa.jpl.aerie.timeline.BoundsTransformer | ||
import gov.nasa.jpl.aerie.timeline.Timeline | ||
import gov.nasa.jpl.aerie.timeline.collections.Instances | ||
import gov.nasa.jpl.aerie.timeline.collections.Intervals | ||
import gov.nasa.jpl.aerie.timeline.collections.Windows | ||
import gov.nasa.jpl.aerie.timeline.collections.profiles.Real | ||
import gov.nasa.jpl.aerie.timeline.ops.* | ||
import gov.nasa.jpl.aerie.timeline.ops.coalesce.CoalesceNoOp | ||
import gov.nasa.jpl.aerie.timeline.payloads.IntervalLike | ||
import gov.nasa.jpl.aerie.timeline.payloads.activities.Activity | ||
import gov.nasa.jpl.aerie.timeline.payloads.activities.Directive | ||
import gov.nasa.jpl.aerie.timeline.payloads.activities.Instance | ||
import gov.nasa.jpl.aerie.timeline.util.preprocessList | ||
|
||
/** A timeline of [Violations][Violation]. */ | ||
data class Violations(private val timeline: Timeline<Violation, Violations>): | ||
Timeline<Violation, Violations> by timeline, | ||
ParallelOps<Violation, Violations>, | ||
NonZeroDurationOps<Violation, Violations>, | ||
CoalesceNoOp<Violation, Violations> | ||
{ | ||
constructor(vararg violation: Violation): this(violation.asList()) | ||
constructor(violations: List<Violation>): this(BaseTimeline(::Violations, preprocessList(violations, null))) | ||
|
||
/** | ||
* Maps the list of associated activity ids on each violation. | ||
* | ||
* @param f a function which takes a [Violation] and returns a new list of ids. | ||
*/ | ||
fun mapIds(f: (Violation) -> List<ActivityId>) = unsafeMap(BoundsTransformer.IDENTITY, false) { it.withNewIds(f(it)) } | ||
|
||
/***/ companion object { | ||
/** Creates a [Violations] object that violates when this profile equals a given value. */ | ||
@JvmStatic fun <V: Any> SerialConstantOps<V, *>.violateOn(v: V) = isolateEqualTo(v).violations() | ||
|
||
/** Creates a [Violations] object that violates when this profile equals a given value. */ | ||
@JvmStatic fun Real.violateOn(n: Number) = equalTo(n).violateOn(true) | ||
|
||
/** | ||
* Creates a [Violations] object that violates on every object in the timeline. | ||
* | ||
* If the object is an activity, it will record the directive or instance id. | ||
*/ | ||
@JvmStatic fun <I: IntervalLike<I>> ParallelOps<I, *>.violations() = | ||
unsafeMap(::Violations, BoundsTransformer.IDENTITY, false) { | ||
Violation( | ||
it.interval, | ||
listOfNotNull(it.getActivityId()) | ||
) | ||
} | ||
|
||
/** Creates a [Violations] object that violates inside each interval. */ | ||
@JvmStatic fun Windows.violateInside() = unsafeCast(::Intervals).violations() | ||
/** Creates a [Violations] object that violates outside each interval. */ | ||
@JvmStatic fun Windows.violateOutside() = complement().violateInside() | ||
|
||
/** | ||
* Creates a [Violations] object from two timelines, that violates whenever they have overlap. | ||
* | ||
* If either object is an activity, it will record the directive or instance id. | ||
*/ | ||
@JvmStatic infix fun <V: IntervalLike<V>, W: IntervalLike<W>> GeneralOps<V, *>.mutex(other: GeneralOps<W, *>) = | ||
unsafeMap2(::Violations, other) { l, r, i -> Violation( | ||
i, | ||
listOfNotNull( | ||
l.getActivityId(), | ||
r.getActivityId() | ||
) | ||
)} | ||
|
||
private fun <V: IntervalLike<V>> V.getActivityId() = when (this) { | ||
is Instance<*> -> InstanceId(id) | ||
is Directive<*> -> DirectiveId(id) | ||
else -> null | ||
} | ||
} | ||
} | ||
|
||
|