diff --git a/build.sbt b/build.sbt index b788a38e3..e8c06dd3a 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,4 @@ -ThisBuild / tlBaseVersion := "0.81" +ThisBuild / tlBaseVersion := "0.82" ThisBuild / tlCiReleaseBranches := Seq("master") ThisBuild / githubWorkflowEnv += "MUNIT_FLAKY_OK" -> "true" diff --git a/modules/core/shared/src/main/scala/lucuma/core/model/sequence/ExecutionConfig.scala b/modules/core/shared/src/main/scala/lucuma/core/model/sequence/ExecutionConfig.scala index bf9abbdd5..2f6241b65 100644 --- a/modules/core/shared/src/main/scala/lucuma/core/model/sequence/ExecutionConfig.scala +++ b/modules/core/shared/src/main/scala/lucuma/core/model/sequence/ExecutionConfig.scala @@ -18,20 +18,8 @@ import monocle.Lens case class ExecutionConfig[S, D]( static: S, acquisition: Option[ExecutionSequence[D]], - science: Option[ExecutionSequence[D]], - setup: SetupTime -) { - - /** - * Execution summary computed from the sequences. - */ - def executionDigest: ExecutionDigest = - ExecutionDigest( - setup, - acquisition.fold(SequenceDigest.Zero)(_.digest), - science.fold(SequenceDigest.Zero)(_.digest) - ) -} + science: Option[ExecutionSequence[D]] +) object ExecutionConfig { @@ -39,8 +27,7 @@ object ExecutionConfig { Eq.by { a => ( a.static, a.acquisition, - a.science, - a.setup + a.science )} /** @group Optics */ @@ -55,8 +42,4 @@ object ExecutionConfig { def science[S, D]: Lens[ExecutionConfig[S, D], Option[ExecutionSequence[D]]] = Focus[ExecutionConfig[S, D]](_.science) - /** @group Optics */ - def setup[S, D]: Lens[ExecutionConfig[S, D], SetupTime] = - Focus[ExecutionConfig[S, D]](_.setup) - } diff --git a/modules/core/shared/src/main/scala/lucuma/core/model/sequence/ExecutionSequence.scala b/modules/core/shared/src/main/scala/lucuma/core/model/sequence/ExecutionSequence.scala index 1b9d5ebe4..613ba19eb 100644 --- a/modules/core/shared/src/main/scala/lucuma/core/model/sequence/ExecutionSequence.scala +++ b/modules/core/shared/src/main/scala/lucuma/core/model/sequence/ExecutionSequence.scala @@ -5,7 +5,6 @@ package lucuma.core.model.sequence import cats.Eq import cats.syntax.all.* -import eu.timepit.refined.types.numeric.PosInt import monocle.Focus import monocle.Lens @@ -23,19 +22,11 @@ import monocle.Lens * not include all potential future atoms that are known * at the time of creation) * @param hasMore whether the `possibleFuture` is incomplete - * @param atomCount number of atoms that we may expect, including the next - * atom, the possible future, and any that haven't been - * included in the possible future - * @param digest compilation of attributes about the sequence as a - * whole, including `possibleFuture` and all expected - * subsequent atoms */ case class ExecutionSequence[D]( nextAtom: Atom[D], possibleFuture: List[Atom[D]], - hasMore: Boolean, - atomCount: PosInt, - digest: SequenceDigest + hasMore: Boolean ) object ExecutionSequence { @@ -52,21 +43,11 @@ object ExecutionSequence { def hasMore[D]: Lens[ExecutionSequence[D], Boolean] = Focus[ExecutionSequence[D]](_.hasMore) - /** @group Optics */ - def atomCount[D]: Lens[ExecutionSequence[D], PosInt] = - Focus[ExecutionSequence[D]](_.atomCount) - - /** @group Optics */ - def digest[D]: Lens[ExecutionSequence[D], SequenceDigest] = - Focus[ExecutionSequence[D]](_.digest) - given [D](using Eq[D]): Eq[ExecutionSequence[D]] = Eq.by { a => ( a.nextAtom, a.possibleFuture, - a.hasMore, - a.atomCount.value, - a.digest + a.hasMore )} } diff --git a/modules/core/shared/src/main/scala/lucuma/core/model/sequence/InstrumentExecutionConfig.scala b/modules/core/shared/src/main/scala/lucuma/core/model/sequence/InstrumentExecutionConfig.scala index fee2bd35c..9b47c9fc6 100644 --- a/modules/core/shared/src/main/scala/lucuma/core/model/sequence/InstrumentExecutionConfig.scala +++ b/modules/core/shared/src/main/scala/lucuma/core/model/sequence/InstrumentExecutionConfig.scala @@ -14,7 +14,6 @@ import monocle.macros.GenPrism */ sealed trait InstrumentExecutionConfig { def instrument: Instrument - def executionDigest: ExecutionDigest } object InstrumentExecutionConfig { @@ -24,9 +23,6 @@ object InstrumentExecutionConfig { ) extends InstrumentExecutionConfig { def instrument: Instrument = Instrument.GmosNorth - - def executionDigest: ExecutionDigest = - executionConfig.executionDigest } object GmosNorth { @@ -42,9 +38,6 @@ object InstrumentExecutionConfig { ) extends InstrumentExecutionConfig { def instrument: Instrument = Instrument.GmosSouth - - def executionDigest: ExecutionDigest = - executionConfig.executionDigest } object GmosSouth { diff --git a/modules/core/shared/src/main/scala/lucuma/core/model/sequence/SequenceDigest.scala b/modules/core/shared/src/main/scala/lucuma/core/model/sequence/SequenceDigest.scala index 6f24e3e4d..aa3c2f9ee 100644 --- a/modules/core/shared/src/main/scala/lucuma/core/model/sequence/SequenceDigest.scala +++ b/modules/core/shared/src/main/scala/lucuma/core/model/sequence/SequenceDigest.scala @@ -7,6 +7,8 @@ import cats.Eq import cats.Monoid import cats.Order.catsKernelOrderingForOrder import cats.syntax.monoid.* +import eu.timepit.refined.cats.* +import eu.timepit.refined.types.numeric.NonNegInt import lucuma.core.enums.ObserveClass import lucuma.core.math.Offset import monocle.Focus @@ -21,11 +23,13 @@ import scala.collection.immutable.SortedSet * @param plannedTime expected execution time for the sequence * @param offsets set of offsets that are expected over the course of the * sequence execution + * @param atomCount number of atoms in the sequence */ case class SequenceDigest( observeClass: ObserveClass, plannedTime: PlannedTime, - offsets: SortedSet[Offset] + offsets: SortedSet[Offset], + atomCount: NonNegInt ) { def add(o: ObserveClass): SequenceDigest = @@ -37,12 +41,13 @@ case class SequenceDigest( def add(o: Offset): SequenceDigest = SequenceDigest.offsets.modify(_ + o)(this) - def add(d: SequenceDigest): SequenceDigest = - SequenceDigest( - observeClass |+| d.observeClass, - plannedTime |+| d.plannedTime, - offsets.union(d.offsets) - ) + def incrementAtomCount: Option[SequenceDigest] = + NonNegInt + .from(atomCount.value + 1) + .toOption + .map { ac => + SequenceDigest.atomCount.replace(ac)(this) + } } @@ -52,7 +57,8 @@ object SequenceDigest { SequenceDigest( Monoid[ObserveClass].empty, PlannedTime.Zero, - SortedSet.empty + SortedSet.empty, + NonNegInt.unsafeFrom(0) ) /** @group Optics */ @@ -67,19 +73,16 @@ object SequenceDigest { val offsets: Lens[SequenceDigest, SortedSet[Offset]] = Focus[SequenceDigest](_.offsets) - given Monoid[SequenceDigest] with { - def empty: SequenceDigest = - Zero - - def combine(a: SequenceDigest, b: SequenceDigest): SequenceDigest = - a.add(b) - } + /** @group Optics */ + val atomCount: Lens[SequenceDigest, NonNegInt] = + Focus[SequenceDigest](_.atomCount) given Eq[SequenceDigest] = Eq.by { a => ( a.observeClass, a.plannedTime, - a.offsets + a.offsets, + a.atomCount )} } diff --git a/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbExecutionConfig.scala b/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbExecutionConfig.scala index e4795ffd4..1c70a432c 100644 --- a/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbExecutionConfig.scala +++ b/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbExecutionConfig.scala @@ -11,7 +11,6 @@ import org.scalacheck.Cogen trait ArbExecutionConfig { import ArbExecutionSequence.given - import ArbSetupTime.given given [S: Arbitrary, D: Arbitrary]: Arbitrary[ExecutionConfig[S, D]] = Arbitrary { @@ -19,13 +18,12 @@ trait ArbExecutionConfig { s <- arbitrary[S] a <- arbitrary[Option[ExecutionSequence[D]]] n <- arbitrary[Option[ExecutionSequence[D]]] - t <- arbitrary[SetupTime] - } yield ExecutionConfig(s, a, n, t) + } yield ExecutionConfig(s, a, n) } given [S: Cogen, D: Cogen]: Cogen[ExecutionConfig[S, D]] = - Cogen[(S, Option[ExecutionSequence[D]], Option[ExecutionSequence[D]], SetupTime)].contramap { a => - (a.static, a.acquisition, a.science, a.setup) + Cogen[(S, Option[ExecutionSequence[D]], Option[ExecutionSequence[D]])].contramap { a => + (a.static, a.acquisition, a.science) } } diff --git a/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbExecutionSequence.scala b/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbExecutionSequence.scala index 9c6ab00f0..1f3dad050 100644 --- a/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbExecutionSequence.scala +++ b/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbExecutionSequence.scala @@ -4,42 +4,32 @@ package lucuma.core.model.sequence package arb -import cats.syntax.all.* -import eu.timepit.refined.types.numeric.PosInt import lucuma.core.util.arb.ArbBoundedCollection import org.scalacheck.Arbitrary import org.scalacheck.Arbitrary.arbitrary import org.scalacheck.Cogen -import org.scalacheck.Gen trait ArbExecutionSequence { import ArbAtom.given import ArbBoundedCollection.* - import ArbSequenceDigest.given given [D: Arbitrary]: Arbitrary[ExecutionSequence[D]] = Arbitrary { for { as <- genBoundedNonEmptyList[Atom[D]](BoundedCollectionLimit) m <- arbitrary[Boolean] - n <- Gen.posNum[Int].map(_ max as.length).map(PosInt.unsafeFrom) - d <- arbitrary[SequenceDigest] - } yield ExecutionSequence(as.head, as.tail, m, n, d) + } yield ExecutionSequence(as.head, as.tail, m) } given [D: Cogen]: Cogen[ExecutionSequence[D]] = Cogen[( Atom[D], List[Atom[D]], - Boolean, - Int, - SequenceDigest + Boolean )].contramap { a => ( a.nextAtom, a.possibleFuture, - a.hasMore, - a.atomCount.value, - a.digest + a.hasMore )} } diff --git a/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbSequenceDigest.scala b/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbSequenceDigest.scala index 21e3d3f6e..f55fc1cab 100644 --- a/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbSequenceDigest.scala +++ b/modules/testkit/src/main/scala/lucuma/core/model/sequence/arb/ArbSequenceDigest.scala @@ -5,6 +5,8 @@ package lucuma.core.model.sequence package arb import cats.Order.catsKernelOrderingForOrder +import eu.timepit.refined.scalacheck.all.* +import eu.timepit.refined.types.numeric.NonNegInt import lucuma.core.enums.ObserveClass import lucuma.core.math.Offset import lucuma.core.math.arb.ArbOffset @@ -26,18 +28,21 @@ trait ArbSequenceDigest { c <- arbitrary[ObserveClass] t <- arbitrary[PlannedTime] o <- arbitrary[SortedSet[Offset]] - } yield SequenceDigest(c, t, o) + n <- arbitrary[NonNegInt] + } yield SequenceDigest(c, t, o, n) } given Cogen[SequenceDigest] = Cogen[( ObserveClass, PlannedTime, - Set[Offset] + Set[Offset], + NonNegInt )].contramap { a => ( a.observeClass, a.plannedTime, - a.offsets + a.offsets, + a.atomCount )} } diff --git a/modules/tests/shared/src/test/scala/lucuma/core/model/sequence/ExecutionConfigSuite.scala b/modules/tests/shared/src/test/scala/lucuma/core/model/sequence/ExecutionConfigSuite.scala index d24249e9d..7e55421c5 100644 --- a/modules/tests/shared/src/test/scala/lucuma/core/model/sequence/ExecutionConfigSuite.scala +++ b/modules/tests/shared/src/test/scala/lucuma/core/model/sequence/ExecutionConfigSuite.scala @@ -19,7 +19,6 @@ final class ExecutionConfigSuite extends DisciplineSuite { import ArbDynamicConfig.* import ArbExecutionConfig.given import ArbExecutionSequence.given - import ArbSetupTime.given import ArbStaticConfig.* override val scalaCheckTestParameters = Test.Parameters.default.withMaxSize(4) @@ -28,5 +27,4 @@ final class ExecutionConfigSuite extends DisciplineSuite { checkAll("ExecutionConfig.static", LensTests(ExecutionConfig.static[StaticConfig.GmosNorth, DynamicConfig.GmosNorth])) checkAll("ExecutionConfig.acquisition", LensTests(ExecutionConfig.acquisition[StaticConfig.GmosNorth, DynamicConfig.GmosNorth])) checkAll("ExecutionConfig.science", LensTests(ExecutionConfig.science[StaticConfig.GmosNorth, DynamicConfig.GmosNorth])) - checkAll("ExecutionConfig.setup", LensTests(ExecutionConfig.setup[StaticConfig.GmosNorth, DynamicConfig.GmosNorth])) } diff --git a/modules/tests/shared/src/test/scala/lucuma/core/model/sequence/SequenceDigestSuite.scala b/modules/tests/shared/src/test/scala/lucuma/core/model/sequence/SequenceDigestSuite.scala index e5f64c149..7350adce8 100644 --- a/modules/tests/shared/src/test/scala/lucuma/core/model/sequence/SequenceDigestSuite.scala +++ b/modules/tests/shared/src/test/scala/lucuma/core/model/sequence/SequenceDigestSuite.scala @@ -4,13 +4,23 @@ package lucuma.core.model.sequence import cats.kernel.laws.discipline.* +import eu.timepit.refined.cats.* +import eu.timepit.refined.scalacheck.all.* +import lucuma.core.model.sequence.arb.ArbPlannedTime import lucuma.core.model.sequence.arb.ArbSequenceDigest +import lucuma.core.util.arb.ArbEnumerated +import monocle.law.discipline.* import munit.* final class SequenceDigestSuite extends DisciplineSuite { + import ArbEnumerated.* + import ArbPlannedTime.given import ArbSequenceDigest.given - checkAll("Eq[SequenceDigest]", EqTests[SequenceDigest].eqv) - checkAll("Monoid[SequenceDigest]", MonoidTests[SequenceDigest].monoid) + checkAll("Eq[SequenceDigest]", EqTests[SequenceDigest].eqv) + checkAll("SequenceDigest.observeClass", LensTests(SequenceDigest.observeClass)) + checkAll("SequenceDigest.plannedTime", LensTests(SequenceDigest.plannedTime)) + checkAll("SequenceDigest.atomCount", LensTests(SequenceDigest.atomCount)) + }