diff --git a/src/main/yuck/constraints/AlldistinctNeighbourhood.scala b/src/main/yuck/constraints/AlldistinctNeighbourhood.scala index 8c2c5d8..a17391c 100644 --- a/src/main/yuck/constraints/AlldistinctNeighbourhood.scala +++ b/src/main/yuck/constraints/AlldistinctNeighbourhood.scala @@ -36,8 +36,8 @@ final class AlldistinctNeighbourhood private val probabilityOfSwappingInValues = moveSizeDistribution.probability(1) private val variablesHaveTheSameDomain = xs.forall(x => x.domain == xs.head.domain) private val swappingInValuesIsPossible = xs.iterator.flatMap(_.domain.valuesIterator).toSet.size > n - private val effects = Vector.fill(3){new ReusableMoveEffect[V]} - private val swaps = for (n <- 1 to 3) yield effects.take(n) + private val effects = Vector.fill(3)(new ReusableMoveEffect[V]) + private val swaps = Vector.tabulate(3)(i => effects.take(i + 1)) private def succeed(n: Int): Move = new ChangeValues[V](space.nextMoveId(), swaps(n - 1)) private def fail: Move = new ChangeValues[V](space.nextMoveId(), Nil) diff --git a/src/main/yuck/constraints/BinPacking.scala b/src/main/yuck/constraints/BinPacking.scala index f50ca3e..9cf8671 100644 --- a/src/main/yuck/constraints/BinPacking.scala +++ b/src/main/yuck/constraints/BinPacking.scala @@ -45,12 +45,10 @@ final class BinPacking override def inVariables = items.view.filter(_.weight > valueTraits.zero).map(_.bin) override def outVariables = loads.view.values - private val x2Item = - (for (item <- items) yield item.bin -> item).toMap[AnyVariable, BinPackingItem[Load]] + private val x2Item = (for (item <- items) yield item.bin -> item).toMap[AnyVariable, BinPackingItem[Load]] private val currentLoads = new mutable.HashMap[Int, Load] // bin -> load private val loadDeltas = new mutable.HashMap[Int, Load] // bin -> load delta - private val effects = // bin -> effect - (for ((i, load) <- loads) yield i -> load.reuseableEffect).toMap + private val effects = for ((i, load) <- loads) yield i -> load.reuseableEffect // bin -> effect override def initialize(now: SearchState) = { currentLoads.clear() diff --git a/src/main/yuck/constraints/CircuitTracker.scala b/src/main/yuck/constraints/CircuitTracker.scala index 1ed4e0c..b799880 100644 --- a/src/main/yuck/constraints/CircuitTracker.scala +++ b/src/main/yuck/constraints/CircuitTracker.scala @@ -73,7 +73,7 @@ abstract class CircuitTracker val indexRange = IntegerRange(offset, offset + succ.size - 1) NoPropagationOccurred .pruneDomains( - for (i <- succ.indices) yield { + for (i <- succ.indices.iterator) yield { val a = IntegerValue(offset + i) (succ(i), succ(i).domain.intersect(indexRange).diff(IntegerRange(a, a))) } @@ -132,4 +132,4 @@ object CircuitTracker { cycles } -} \ No newline at end of file +} diff --git a/src/main/yuck/constraints/Cumulative.scala b/src/main/yuck/constraints/Cumulative.scala index 57c83d8..1487f97 100644 --- a/src/main/yuck/constraints/Cumulative.scala +++ b/src/main/yuck/constraints/Cumulative.scala @@ -109,7 +109,7 @@ final class Cumulative buf += i map } - .map{case (x, buf) => (x, buf.toIndexedSeq)} + .map{case (x, buf) => (x, buf.toVector)} .toMap private val effect = costs.reuseableEffect diff --git a/src/main/yuck/constraints/Disjoint.scala b/src/main/yuck/constraints/Disjoint.scala index 4c9bff7..c468d28 100644 --- a/src/main/yuck/constraints/Disjoint.scala +++ b/src/main/yuck/constraints/Disjoint.scala @@ -53,7 +53,7 @@ abstract class Disjoint buf += i map } - .map{case (x, buf) => (x, buf.toIndexedSeq)} + .map{case (x, buf) => (x, buf.toVector)} .toMap private val effect = costs.reuseableEffect diff --git a/src/main/yuck/constraints/GeneralInverseNeighbourhood.scala b/src/main/yuck/constraints/GeneralInverseNeighbourhood.scala index be9d8d9..7c09bd2 100644 --- a/src/main/yuck/constraints/GeneralInverseNeighbourhood.scala +++ b/src/main/yuck/constraints/GeneralInverseNeighbourhood.scala @@ -19,8 +19,9 @@ final class GeneralInverseNeighbourhood private val effects = Vector.fill(4){new ReusableMoveEffect[IntegerValue]} private val candidates1 = - f.xs.indices + f.xs.indices.iterator .filter(i => f.xs(i).domain.size > 1 && g.xs(rawValue(f.xs(i)) - g.offset).domain.size > 1) + .toVector override def nextMove = { if (candidates1.isEmpty) { @@ -50,7 +51,7 @@ final class GeneralInverseNeighbourhood x1.domain.contains(a2) && x2.domain.contains(a1) && y1.domain.contains(b2) && y2.domain.contains(b1) }) - .toIndexedSeq + .toVector if (candidates2.isEmpty) { new ChangeValues[IntegerValue](space.nextMoveId(), Nil) } else { diff --git a/src/main/yuck/constraints/Inverse.scala b/src/main/yuck/constraints/Inverse.scala index 59e997f..1206baa 100644 --- a/src/main/yuck/constraints/Inverse.scala +++ b/src/main/yuck/constraints/Inverse.scala @@ -82,8 +82,8 @@ final class Inverse private def propagate(effects: PropagationEffects, f: InverseFunction, g: InverseFunction): PropagationEffects = { effects - .pruneDomains(for (x <- f.xs) yield (x, g.indexDomain)) - .pruneDomains(for (x <- g.xs) yield (x, f.indexDomain)) + .pruneDomains(for (x <- f.xs.iterator) yield (x, g.indexDomain)) + .pruneDomains(for (x <- g.xs.iterator) yield (x, f.indexDomain)) .pruneDomains( for (i <- f.indexRange.iterator; x = f.xs(i - f.offset); @@ -339,15 +339,15 @@ final class Inverse fPartitionByDomain.keysIterator.foldLeft[IntegerDomain](EmptyIntegerRange){union}.size == fPartitionByDomain.keysIterator.map(_.size).sum if (isDecomposable) { - for (domain <- fPartitionByDomain.keysIterator.toList) yield { + fPartitionByDomain.keysIterator.map(domain => { val offset = domain.lb.toInt val costs = new BooleanVariable(space.nextVariableId(), "", CompleteBooleanDomain) new Inverse( space.nextConstraintId(), maybeGoal, - new InverseFunction(fPartitionByDomain(domain).toIndexedSeq, offset), - new InverseFunction(gPartitionByDomain(domain).toIndexedSeq, offset), + new InverseFunction(fPartitionByDomain(domain).toVector, offset), + new InverseFunction(gPartitionByDomain(domain).toVector, offset), costs) - } + }).toList } else { List(this) } diff --git a/src/main/yuck/constraints/Regular.scala b/src/main/yuck/constraints/Regular.scala index 4ce0acb..1f6901f 100644 --- a/src/main/yuck/constraints/Regular.scala +++ b/src/main/yuck/constraints/Regular.scala @@ -74,7 +74,7 @@ final class Regular for (j <- 0 until Q) if (d(i)(k) < Int.MaxValue && d(k)(j) < Int.MaxValue && d(i)(j) > d(i)(k) + d(k)(j)) d(i)(j) = d(i)(k) + d(k)(j) - for (i <- 0 until Q) yield F.valuesIterator.map(f => d(i)(f.toInt - 1)).min + Vector.tabulate(Q)(i => F.valuesIterator.map(f => d(i)(f.toInt - 1)).min) } override def toString = @@ -98,7 +98,7 @@ final class Regular buf += i map } - .map{case (x, buf) => (x, buf.toIndexedSeq)} + .map{case (x, buf) => (x, buf.toVector)} .toMap } else { null @@ -116,7 +116,7 @@ final class Regular private val effect = costs.reuseableEffect override def initialize(now: SearchState) = { - currentStates = immutable.IndexedSeq[Int]() ++ (0 until n).map(i => 0) + currentStates = Vector.fill(n)(0) var i = 0 var q = q0 while (i < n && q > 0) { diff --git a/src/main/yuck/constraints/Table.scala b/src/main/yuck/constraints/Table.scala index 1bc821a..4e0ffef 100644 --- a/src/main/yuck/constraints/Table.scala +++ b/src/main/yuck/constraints/Table.scala @@ -58,7 +58,7 @@ final class Table buf += i map } - .map{case (x, buf) => (x, buf.toIndexedSeq)} + .map{case (x, buf) => (x, buf.toVector)} .toMap } else { null diff --git a/src/main/yuck/core/IntegerDomain.scala b/src/main/yuck/core/IntegerDomain.scala index e494bfa..c7bb66f 100644 --- a/src/main/yuck/core/IntegerDomain.scala +++ b/src/main/yuck/core/IntegerDomain.scala @@ -241,7 +241,7 @@ object IntegerDomain { def apply(ranges: Iterable[IntegerRange]): IntegerDomain = { if (ranges.isEmpty) EmptyIntegerRange else if (ranges.size == 1) ranges.head - else new IntegerRangeList(ranges.toIndexedSeq) + else new IntegerRangeList(ranges.toVector) } /** diff --git a/src/main/yuck/core/IntegerRangeList.scala b/src/main/yuck/core/IntegerRangeList.scala index 5431643..5c38f8d 100644 --- a/src/main/yuck/core/IntegerRangeList.scala +++ b/src/main/yuck/core/IntegerRangeList.scala @@ -194,7 +194,7 @@ final class IntegerRangeList override def mirrored: IntegerRangeList = if (isEmpty) this - else new IntegerRangeList(ranges.reverseIterator.map(_.mirrored).toIndexedSeq) + else new IntegerRangeList(ranges.reverseIterator.map(_.mirrored).toVector) private def cannotIntersect(that: IntegerRangeList): Boolean = this.isEmpty || @@ -263,7 +263,7 @@ object IntegerRangeList { */ def apply(range: IntegerRange) = if (range.isEmpty) EmptyIntegerRangeList - else new IntegerRangeList(immutable.IndexedSeq(range)) + else new IntegerRangeList(Vector(range)) /** * Creates an IntegerRangeList instance from the given boundaries. @@ -272,7 +272,7 @@ object IntegerRangeList { */ def apply(a: IntegerValue, b: IntegerValue) = if (a.ne(null) && b.ne(null) && b < a) EmptyIntegerRangeList - else new IntegerRangeList(immutable.IndexedSeq(IntegerRange(a, b))) + else new IntegerRangeList(Vector(IntegerRange(a, b))) // In the following methods we prefer indices and tail recursion over iterators and loops // to avoid the overhead of creating ranges and iterators. diff --git a/src/main/yuck/core/RandomCircularSwapGenerator.scala b/src/main/yuck/core/RandomCircularSwapGenerator.scala index 4fda731..51e5717 100644 --- a/src/main/yuck/core/RandomCircularSwapGenerator.scala +++ b/src/main/yuck/core/RandomCircularSwapGenerator.scala @@ -51,12 +51,11 @@ final class RandomCircularSwapGenerator require(moveSizeDistribution.frequency(0) == 0) require(moveSizeDistribution.volume > 0) - private val uniformDistribution = Distribution(n) - (0 until n).foreach(i => uniformDistribution.setFrequency(i, 1)) + private val uniformDistribution = Distribution(0, Vector.fill(n)(1)) private val s = moveSizeDistribution.size - private val effects = for (i <- 1 until s) yield new ReusableMoveEffect[V] - private val swaps = for (n <- 1 until s) yield effects.take(n) - private val frequencyRestorers = for (i <- 1 until s) yield new FrequencyRestorer + private val effects = Vector.fill(s)(new ReusableMoveEffect[V]) + private val swaps = Vector.tabulate(s)(i => effects.take(i + 1)) + private val frequencyRestorers = Vector.fill(s)(new FrequencyRestorer) private def fillEffect(effect: ReusableMoveEffect[V], x: Variable[V]): Unit = { effect.x = x effect.a = space.searchState.value(x) diff --git a/src/main/yuck/core/RandomReassignmentGenerator.scala b/src/main/yuck/core/RandomReassignmentGenerator.scala index 11819e1..0e7c60e 100644 --- a/src/main/yuck/core/RandomReassignmentGenerator.scala +++ b/src/main/yuck/core/RandomReassignmentGenerator.scala @@ -43,12 +43,10 @@ final class RandomReassignmentGenerator require(moveSizeDistribution.frequency(0) == 0) require(moveSizeDistribution.volume > 0) - private val uniformDistribution = Distribution(n) - (0 until n).foreach(i => uniformDistribution.setFrequency(i, 1)) - require(uniformDistribution.volume > 0) - private val s = moveSizeDistribution.size + private val uniformDistribution = Distribution(0, Vector.fill(n)(1)) private val effects = new mutable.ArrayBuffer[AnyMoveEffect](n) - private val frequencyRestorers = for (i <- 1 until s) yield new FrequencyRestorer + private val s = moveSizeDistribution.size + private val frequencyRestorers = Vector.fill(s)(new FrequencyRestorer) private def addEffect(x: AnyVariable): Unit = { effects += x.nextRandomMoveEffect(space, randomGenerator) } diff --git a/src/main/yuck/flatzinc/compiler/CompilationPhase.scala b/src/main/yuck/flatzinc/compiler/CompilationPhase.scala index cc73c19..143a037 100644 --- a/src/main/yuck/flatzinc/compiler/CompilationPhase.scala +++ b/src/main/yuck/flatzinc/compiler/CompilationPhase.scala @@ -124,7 +124,7 @@ abstract class CompilationPhase extends Runnable { case Term(_, Nil) => cc.arrays(expr) case ArrayConst(elems) => - val array = elems.iterator.map(elem => compileAnyExpr(elem)).to(immutable.ArraySeq) + val array = elems.iterator.map(elem => compileAnyExpr(elem)).toVector cc.arrayConsts += expr -> array array } diff --git a/src/main/yuck/flatzinc/compiler/ConstraintDrivenNeighbourhoodFactory.scala b/src/main/yuck/flatzinc/compiler/ConstraintDrivenNeighbourhoodFactory.scala index 7d1cc0c..e9cc59a 100644 --- a/src/main/yuck/flatzinc/compiler/ConstraintDrivenNeighbourhoodFactory.scala +++ b/src/main/yuck/flatzinc/compiler/ConstraintDrivenNeighbourhoodFactory.scala @@ -109,7 +109,7 @@ final class ConstraintDrivenNeighbourhoodFactory val xs0 = cc.space.involvedSearchVariables(constraint) neighbourhoods ++= neighbourhoodsFromImplicitConstraints.iterator.filter(_.searchVariables.intersect(xs0).nonEmpty) - val xs = xs0.diff(cc.implicitlyConstrainedVars).toBuffer.sorted.toIndexedSeq + val xs = xs0.diff(cc.implicitlyConstrainedVars).toBuffer.sorted.toVector if (xs.isEmpty) { // Either there are no variables or they are all managed by neighbourhoods from implicit constraints. None @@ -123,7 +123,7 @@ final class ConstraintDrivenNeighbourhoodFactory if (neighbourhoods.size < 2) { neighbourhoods.headOption } else { - Some(new NeighbourhoodCollection(neighbourhoods.toIndexedSeq, randomGenerator, None, None)) + Some(new NeighbourhoodCollection(neighbourhoods.toVector, randomGenerator, None, None)) } } } @@ -143,7 +143,7 @@ final class ConstraintDrivenNeighbourhoodFactory if (weights.isEmpty) { None } else { - val xs = weights.map(_.x).toIndexedSeq + val xs = weights.map(_.x).toVector for (x <- xs if ! x.domain.isFinite) { throw new VariableWithInfiniteDomainException(x) } @@ -181,7 +181,7 @@ final class ConstraintDrivenNeighbourhoodFactory val (weights, neighbourhoods) = weightedNeighbourhoods.unzip val hotSpotDistribution = createHotSpotDistribution(mode, weights) Some(new NeighbourhoodCollection( - neighbourhoods.toIndexedSeq, randomGenerator, Some(hotSpotDistribution), None)) + neighbourhoods.toVector, randomGenerator, Some(hotSpotDistribution), None)) } maybeNeighbourhood.map(considerFairVariableChoiceRate(_, levelCfg)) } @@ -194,7 +194,7 @@ final class ConstraintDrivenNeighbourhoodFactory Distribution = { val hotSpotDistribution = Distribution(weights.size) - cc.space.post(new OptimizationGoalTracker(nextConstraintId(), None, mode, weights.toIndexedSeq, hotSpotDistribution)) + cc.space.post(new OptimizationGoalTracker(nextConstraintId(), None, mode, weights.toVector, hotSpotDistribution)) hotSpotDistribution } @@ -204,7 +204,7 @@ final class ConstraintDrivenNeighbourhoodFactory val rate = (levelCfg.maybeFairVariableChoiceRate.getOrElse(Probability(0)).value * 100).toInt if (rate == 0) neighbourhood0 else { - val xs = neighbourhood0.searchVariables.diff(cc.implicitlyConstrainedVars).toBuffer.sorted.toIndexedSeq + val xs = neighbourhood0.searchVariables.diff(cc.implicitlyConstrainedVars).toBuffer.sorted.toVector if (xs.isEmpty) neighbourhood0 else { val neighbourhood1 = diff --git a/src/main/yuck/flatzinc/compiler/ConstraintFactory.scala b/src/main/yuck/flatzinc/compiler/ConstraintFactory.scala index a25fb58..a3e1fdb 100644 --- a/src/main/yuck/flatzinc/compiler/ConstraintFactory.scala +++ b/src/main/yuck/flatzinc/compiler/ConstraintFactory.scala @@ -567,9 +567,9 @@ final class ConstraintFactory assert(xs.size == ws.size) val y = compileConstant(Zero) val h = compileConstant(One) - val rects = for (i <- xs.indices) yield new Disjoint2Rect(xs(i), y, ws(i), h) + val rects = Vector.tabulate(xs.size)(i => new Disjoint2Rect(xs(i), y, ws(i), h)) val costs = maybeCosts.getOrElse(createBoolChannel()) - cc.space.post(new Disjoint2(nextConstraintId(), maybeGoal, rects.to(immutable.ArraySeq), strict, costs)) + cc.space.post(new Disjoint2(nextConstraintId(), maybeGoal, rects, strict, costs)) List(costs) case Constraint("yuck_diffn", Seq(x, y, w, h, BoolConst(strict)), _) => val xs = compileIntArray(x) @@ -579,26 +579,26 @@ final class ConstraintFactory assert(xs.size == ys.size) assert(xs.size == ws.size) assert(xs.size == hs.size) - val rects = for (i <- xs.indices) yield new Disjoint2Rect(xs(i), ys(i), ws(i), hs(i)) + val rects = Vector.tabulate(xs.size)(i => new Disjoint2Rect(xs(i), ys(i), ws(i), hs(i))) val costs = maybeCosts.getOrElse(createBoolChannel()) - cc.space.post(new Disjoint2(nextConstraintId(), maybeGoal, rects.to(immutable.ArraySeq), strict, costs)) + cc.space.post(new Disjoint2(nextConstraintId(), maybeGoal, rects, strict, costs)) List(costs) case Constraint("yuck_table_bool", Seq(as, flatTable), _) => val xs = compileBoolArray(as) - val rows = compileBoolArray(flatTable).map(_.domain.singleValue).grouped(xs.size).to(immutable.ArraySeq) + val rows = compileBoolArray(flatTable).map(_.domain.singleValue).grouped(xs.size).toVector val costs = maybeCosts.getOrElse(createBoolChannel()) val forceImplicitSolving = constraint.annotations.exists(forcesImplicitSolving) cc.space.post(new Table(nextConstraintId(), maybeGoal, xs, rows, costs, forceImplicitSolving)) List(costs) case Constraint("yuck_table_int", Seq(as, flatTable), _) => val xs = compileIntArray(as) - val rows = compileIntArray(flatTable).map(_.domain.singleValue).grouped(xs.size).to(immutable.ArraySeq) + val rows = compileIntArray(flatTable).map(_.domain.singleValue).grouped(xs.size).toVector val costs = maybeCosts.getOrElse(createBoolChannel()) val forceImplicitSolving = constraint.annotations.exists(forcesImplicitSolving) cc.space.post(new Table(nextConstraintId(), maybeGoal, xs, rows, costs, forceImplicitSolving)) List(costs) case Constraint("yuck_regular", Seq(xs, q, s, flatDelta, q0, f), _) => - val delta = compileIntArray(flatDelta).map(_.domain.singleValue.toInt).grouped(s.toInt).to(immutable.ArraySeq) + val delta = compileIntArray(flatDelta).map(_.domain.singleValue.toInt).grouped(s.toInt).toVector val costs = maybeCosts.getOrElse(createBoolChannel()) cc.space.post(new Regular(nextConstraintId(), maybeGoal, xs, q.toInt, s.toInt, delta, q0.toInt, f.set, costs)) List(costs) @@ -622,7 +622,7 @@ final class ConstraintFactory val itemGenerator = for ((bin, weight) <- bins.iterator.zip(weights.iterator)) yield new BinPackingItem(bin, weight) - val items = itemGenerator.toIndexedSeq + val items = itemGenerator.toVector val loads1 = compileIntArray(loads0) val loads = (minLoadIndex until minLoadIndex + loads1.size).iterator.zip(loads1.iterator).toMap compileBinPackingConstraint(maybeGoal, constraint, items, loads) @@ -812,7 +812,7 @@ final class ConstraintFactory .iterator .filter{case (_, weight) => weight > loadTraits.zero} .map{case (bin, weight) => new BinPackingItem(bin, weight)} - .toIndexedSeq + .toVector val bins = items1.map(_.bin) val maxLoad = items.map(_.weight).sum(loadTraits.numericalOperations) val trivialLoadDomain = loadTraits.createDomain(loadTraits.zero, maxLoad) @@ -868,7 +868,7 @@ final class ConstraintFactory if (serviceTimes1.isEmpty) _ => timeTraits.zero else i => serviceTimes1(i) val travelTimes1 = compileNumArray[Time](travelTimes0).map(_.domain.singleValue).grouped(arrivalTimes.size) - .to(immutable.ArraySeq) + .toVector require(travelTimes1.isEmpty || (travelTimes1.size == nodes.size && travelTimes1.forall(_.size == nodes.size))) val travelTimesAreSymmetric = travelTimes1.isEmpty || @@ -876,7 +876,7 @@ final class ConstraintFactory i => Range(i + 1, nodes.size).forall(j => travelTimes1(i)(j) == travelTimes1(j)(i))) val travelTimes2 = if (! travelTimes1.isEmpty && travelTimesAreSymmetric) - (for (i <- 0 until nodes.size) yield travelTimes1(i).drop(i)).to(immutable.ArraySeq) + Vector.tabulate(nodes.size)(i => travelTimes1(i).drop(i)) else travelTimes1 val travelTimes: (Int, Int) => Time = if (travelTimes2.isEmpty) (_, _) => timeTraits.zero @@ -907,7 +907,7 @@ final class ConstraintFactory val arrivalTimes1: immutable.IndexedSeq[NumericalVariable[Time]] = { val definableVars = this.definedVars(constraint) val definedVars = new mutable.HashSet[NumericalVariable[Time]] - for (i <- nodes.values.toIndexedSeq) yield { + nodes.valuesIterator.map(i => val arrivalTime = arrivalTimes(safeToInt(safeSub(i.value, offset))) if (startNodes.contains(i)) { arrivalTime @@ -919,7 +919,7 @@ final class ConstraintFactory arrivalTime } else timeTraits.createVariable(cc.space, "", arrivalTime.domain) - } + ).toVector } val totalTravelTime1: NumericalVariable[Time] = if (isViableConstraint(succ, totalTravelTime)) totalTravelTime @@ -985,11 +985,11 @@ final class ConstraintFactory val List(AX(_, x), AX(_, y)) = axs cc.space.post(new Plus(nextConstraintId(), maybeGoal, x, y, channel)) } else { - val xs = axs.iterator.map(_.x).toIndexedSeq + val xs = axs.iterator.map(_.x).toVector cc.space.post(new Sum(nextConstraintId(), maybeGoal, xs , channel)) } } else { - cc.space.post(new LinearCombination(nextConstraintId(), maybeGoal, axs.toIndexedSeq, channel)) + cc.space.post(new LinearCombination(nextConstraintId(), maybeGoal, axs.toVector, channel)) } channel } @@ -1016,9 +1016,9 @@ final class ConstraintFactory val z = compileNumExpr[V](c) val costs = maybeCosts.getOrElse(createBoolChannel()) if (axs.forall(_.a == valueTraits.one)) { - cc.space.post(new SumConstraint(nextConstraintId(), maybeGoal, axs.map(_.x).to(immutable.ArraySeq), y, relation, z, costs)) + cc.space.post(new SumConstraint(nextConstraintId(), maybeGoal, axs.map(_.x).toVector, y, relation, z, costs)) } else { - cc.space.post(new LinearConstraint(nextConstraintId(), maybeGoal, axs.to(immutable.ArraySeq), y, relation, z, costs)) + cc.space.post(new LinearConstraint(nextConstraintId(), maybeGoal, axs.toVector, y, relation, z, costs)) } costs } @@ -1098,7 +1098,7 @@ final class ConstraintFactory val xs1 = xs0.drop(max(0, i.domain.lb.toInt - indexRange0.lb.toInt)).take(indexRange.size) val xs = (for (j <- indexRange.values) yield xs1((if (i.domain.contains(j)) j else i.domain.lb).toInt - offset)) - .toIndexedSeq + .toVector def post(y: OrderedVariable[V]): OrderedVariable[V] = { if (xs.forall(_.domain.isSingleton)) { val as = xs.map(_.domain.singleValue) @@ -1172,14 +1172,14 @@ final class ConstraintFactory compileConstraint(reifiedConstraint, List(satisfied), functionalCase, generalCase) } else { def functionalCase = { - val costs0 = compileConstraint(maybeGoal, constraint, Some(satisfied)).toIndexedSeq + val costs0 = compileConstraint(maybeGoal, constraint, Some(satisfied)).toVector if (costs0.size != 1 || costs0.head != satisfied) { postConjunction(maybeGoal, costs0, Some(satisfied)) } enforceBoolDomain(satisfied) } def generalCase = { - val costs0 = compileConstraint(maybeGoal, constraint, None).toIndexedSeq + val costs0 = compileConstraint(maybeGoal, constraint, None).toVector val costs = createBoolChannel() if (costs0.size == 1) { cc.space.post(new Eq(nextConstraintId(), maybeGoal, costs0.head, satisfied, costs)) @@ -1197,7 +1197,7 @@ final class ConstraintFactory (maybeGoal: Option[Goal], xs0: Seq[BooleanVariable], maybeY: Option[BooleanVariable] = None): BooleanVariable = { - val xs = xs0.iterator.filterNot(_.domain == FalseDomain).toSet.to(immutable.ArraySeq) + val xs = xs0.iterator.filterNot(_.domain == FalseDomain).toSet.toVector if (xs.size == 1 && maybeY.isEmpty) { xs(0) } else { @@ -1215,7 +1215,7 @@ final class ConstraintFactory (maybeGoal: Option[Goal], xs0: Seq[BooleanVariable], maybeY: Option[BooleanVariable] = None): BooleanVariable = { - val xs = xs0.iterator.filterNot(_.domain == TrueDomain).toSet.to(immutable.ArraySeq) + val xs = xs0.iterator.filterNot(_.domain == TrueDomain).toSet.toVector if (xs.size == 1 && maybeY.isEmpty) { xs(0) } else { @@ -1308,7 +1308,7 @@ final class ConstraintFactory .map(_.get) .filter(_.isInstanceOf[Contains]) .filter(_.maybeGoal == Some(DomainEnforcementGoal)) - .to(immutable.ArraySeq) + .toVector if (intDomainEnforcementConstraints.size > 32) { // When there are many integer channels, we enforce their domains using a single InDomain constraint. // This way we speed up neighbourhood generation and reduce the overhead of goal tracking. diff --git a/src/main/yuck/flatzinc/compiler/NeighbourhoodFactory.scala b/src/main/yuck/flatzinc/compiler/NeighbourhoodFactory.scala index acdd104..b9d4387 100644 --- a/src/main/yuck/flatzinc/compiler/NeighbourhoodFactory.scala +++ b/src/main/yuck/flatzinc/compiler/NeighbourhoodFactory.scala @@ -74,7 +74,7 @@ abstract class NeighbourhoodFactory extends CompilationPhase { if (neighbourhoods.size < 2) { neighbourhoods.headOption } else { - Some(stackNeighbourhoods(objectives.toIndexedSeq, neighbourhoods.toIndexedSeq)) + Some(stackNeighbourhoods(objectives.toVector, neighbourhoods.toVector)) } } @@ -117,7 +117,7 @@ abstract class NeighbourhoodFactory extends CompilationPhase { } } } - val xs = cc.space.involvedSearchVariables(x).diff(cc.implicitlyConstrainedVars).toBuffer.sorted.toIndexedSeq + val xs = cc.space.involvedSearchVariables(x).diff(cc.implicitlyConstrainedVars).toBuffer.sorted.toVector if (! xs.isEmpty && ! cc.sigint.isSet) { for (x <- xs if ! x.domain.isFinite) { throw new VariableWithInfiniteDomainException(x) @@ -138,7 +138,7 @@ abstract class NeighbourhoodFactory extends CompilationPhase { neighbourhoods.headOption } else { Some(new NeighbourhoodCollection( - neighbourhoods.toIndexedSeq, randomGenerator, + neighbourhoods.toVector, randomGenerator, if (levelCfg.guideOptimization) Some(createHotSpotDistribution2(neighbourhoods)) else None, if (levelCfg.guideOptimization) levelCfg.maybeFairVariableChoiceRate else None)) } @@ -164,7 +164,7 @@ abstract class NeighbourhoodFactory extends CompilationPhase { val searchVarIndex = searchVars.iterator.zipWithIndex.toMap val hotSpotDistribution = Distribution(searchVars.size) def involvedSearchVars(x: AnyVariable) = - cc.space.involvedSearchVariables(x).diff(cc.implicitlyConstrainedVars).iterator.map(searchVarIndex).toIndexedSeq + cc.space.involvedSearchVariables(x).diff(cc.implicitlyConstrainedVars).iterator.map(searchVarIndex).toVector val involvementMatrix = costVars.iterator.map(x => (x, involvedSearchVars(x))).filter(_._2.nonEmpty).toMap cc.space.post(new SatisfactionGoalTracker(cc.space.nextConstraintId(), None, involvementMatrix, hotSpotDistribution)) hotSpotDistribution @@ -179,7 +179,7 @@ abstract class NeighbourhoodFactory extends CompilationPhase { val ys = neighbourhood.searchVariables.toSet xs.exists(ys.contains) } - neighbourhoods.iterator.filter(isInvolved).map(neighbourhoodIndex).toIndexedSeq + neighbourhoods.iterator.filter(isInvolved).map(neighbourhoodIndex).toVector } val involvementMatrix = cc.costVars.iterator.map(x => (x, involvedNeighbourhoods(x))).filter(_._2.nonEmpty).toMap cc.space.post(new SatisfactionGoalTracker(cc.space.nextConstraintId(), None, involvementMatrix, hotSpotDistribution)) @@ -215,7 +215,7 @@ abstract class NeighbourhoodFactory extends CompilationPhase { } else { cc.logger.logg("Adding a neighbourhood over %s".format(xs)) Some(new RandomReassignmentGenerator( - cc.space, xs.toBuffer.sorted.toIndexedSeq, randomGenerator, cc.cfg.moveSizeDistribution, None, None)) + cc.space, xs.toBuffer.sorted.toVector, randomGenerator, cc.cfg.moveSizeDistribution, None, None)) } } diff --git a/src/main/yuck/flatzinc/compiler/ObjectiveFactory.scala b/src/main/yuck/flatzinc/compiler/ObjectiveFactory.scala index b4880ca..32a28e1 100644 --- a/src/main/yuck/flatzinc/compiler/ObjectiveFactory.scala +++ b/src/main/yuck/flatzinc/compiler/ObjectiveFactory.scala @@ -58,7 +58,7 @@ final class ObjectiveFactory SatisfactionObjective = { val costVar = createBoolChannel() - cc.space.post(new Conjunction(nextConstraintId(), None, costVars.toIndexedSeq, costVar)) + cc.space.post(new Conjunction(nextConstraintId(), None, costVars.toVector, costVar)) createSatisfactionObjective(cfg, costVar) } diff --git a/src/main/yuck/flatzinc/compiler/VariableDrivenNeighbourhoodFactory.scala b/src/main/yuck/flatzinc/compiler/VariableDrivenNeighbourhoodFactory.scala index 6937ac0..f97bd1c 100644 --- a/src/main/yuck/flatzinc/compiler/VariableDrivenNeighbourhoodFactory.scala +++ b/src/main/yuck/flatzinc/compiler/VariableDrivenNeighbourhoodFactory.scala @@ -55,7 +55,7 @@ final class VariableDrivenNeighbourhoodFactory val neighbourhoods = new mutable.ArrayBuffer[Neighbourhood] val remainingVariables = hotSpotIndicators.keys.toSet -- cc.implicitlyConstrainedVars if (! remainingVariables.isEmpty) { - val xs = remainingVariables.toBuffer.sorted.toIndexedSeq + val xs = remainingVariables.toBuffer.sorted.toVector for (x <- xs if ! x.domain.isFinite) { throw new VariableWithInfiniteDomainException(x) } @@ -68,7 +68,7 @@ final class VariableDrivenNeighbourhoodFactory if (neighbourhoods.size < 2) { neighbourhoods.headOption } else { - Some(new NeighbourhoodCollection(neighbourhoods.toIndexedSeq, randomGenerator, None, None)) + Some(new NeighbourhoodCollection(neighbourhoods.toVector, randomGenerator, None, None)) } } @@ -130,9 +130,9 @@ final class VariableDrivenNeighbourhoodFactory s += x -> createNonNegativeChannel[V]() val zl = AX.normalize(zs(x)) if (zl.forall(ax => ax.a == valueTraits.one)) { - cc.space.post(new Sum(nextConstraintId(), None, zl.iterator.map(ax => ax.x).toIndexedSeq, s(x))) + cc.space.post(new Sum(nextConstraintId(), None, zl.iterator.map(ax => ax.x).toVector, s(x))) } else { - cc.space.post(new LinearCombination(nextConstraintId(), None, zl.toIndexedSeq, s(x))) + cc.space.post(new LinearCombination(nextConstraintId(), None, zl.toVector, s(x))) } } s @@ -146,7 +146,7 @@ final class VariableDrivenNeighbourhoodFactory Option[Distribution] = { val hotSpotDistribution = Distribution(xs.size) - val weightedIndicators = xs.iterator.map(x => new AX(valueTraits.one, hotSpotIndicators(x))).toIndexedSeq + val weightedIndicators = xs.iterator.map(x => new AX(valueTraits.one, hotSpotIndicators(x))).toVector cc.space.post(new OptimizationGoalTracker(nextConstraintId(), None, OptimizationMode.Min, weightedIndicators, hotSpotDistribution)) Some(hotSpotDistribution) } diff --git a/src/main/yuck/flatzinc/compiler/VariableFactory.scala b/src/main/yuck/flatzinc/compiler/VariableFactory.scala index c395857..cbc0138 100644 --- a/src/main/yuck/flatzinc/compiler/VariableFactory.scala +++ b/src/main/yuck/flatzinc/compiler/VariableFactory.scala @@ -1,5 +1,7 @@ package yuck.flatzinc.compiler +import scala.collection.* + import yuck.core.{given, *} import yuck.flatzinc.ast.* @@ -21,9 +23,9 @@ final class VariableFactory override def run() = { cc.ast.paramDecls.iterator.filterNot(_.valueType.isArrayType).foreach(createVariable) - cc.ast.paramDecls.iterator.filter(_.valueType.isArrayType).foreach(createVariable) + cc.ast.paramDecls.iterator.filter(_.valueType.isArrayType).foreach(createVariables) cc.ast.varDecls.iterator.filterNot(_.valueType.isArrayType).foreach(createVariable) - cc.ast.varDecls.iterator.filter(_.valueType.isArrayType).foreach(createVariable) + cc.ast.varDecls.iterator.filter(_.valueType.isArrayType).foreach(createVariables) } import HighPriorityImplicits.* @@ -36,27 +38,19 @@ final class VariableFactory createVariable[IntegerValue](Term(decl.id, Nil)) case IntSetType(_) => createVariable[IntegerSetValue](Term(decl.id, Nil)) + case other => + throw new UnsupportedFlatZincTypeException(other) + } + } + + private def createVariables(decl: PlaceholderDecl): Unit = { + decl.valueType match { case ArrayType(Some(IntRange(1, n)), BoolType) => - val array = - for (idx <- 1 to n.toInt) yield { - val key = ArrayAccess(decl.id, IntConst(idx)) - createVariable[BooleanValue](key) - } - cc.arrays += Term(decl.id, Nil) -> array + cc.arrays += Term(decl.id, Nil) -> createArray[BooleanValue](decl, n.toInt) case ArrayType(Some(IntRange(1, n)), IntType(_)) => - val array = - for (idx <- 1 to n.toInt) yield { - val key = ArrayAccess(decl.id, IntConst(idx)) - createVariable[IntegerValue](key) - } - cc.arrays += Term(decl.id, Nil) -> array + cc.arrays += Term(decl.id, Nil) -> createArray[IntegerValue](decl, n.toInt) case ArrayType(Some(IntRange(1, n)), IntSetType(_)) => - val array = - for (idx <- 1 to n.toInt) yield { - val key = ArrayAccess(decl.id, IntConst(idx)) - createVariable[IntegerSetValue](key) - } - cc.arrays += Term(decl.id, Nil) -> array + cc.arrays += Term(decl.id, Nil) -> createArray[IntegerSetValue](decl, n.toInt) case other => throw new UnsupportedFlatZincTypeException(other) } @@ -89,4 +83,13 @@ final class VariableFactory } } + private def createArray + [V <: Value[V]] + (decl: PlaceholderDecl, n: Int) + (using valueTraits: ValueTraits[V]): + immutable.IndexedSeq[Variable[V]] = + { + Vector.tabulate(n)(idx => createVariable(ArrayAccess(decl.id, IntConst(idx + 1)))) + } + } diff --git a/src/main/yuck/flatzinc/parser/FlatZincParser.scala b/src/main/yuck/flatzinc/parser/FlatZincParser.scala index be40b52..c0a5db5 100644 --- a/src/main/yuck/flatzinc/parser/FlatZincParser.scala +++ b/src/main/yuck/flatzinc/parser/FlatZincParser.scala @@ -59,7 +59,7 @@ object FlatZincParser extends RegexParsers { int_range ^^ (r => IntSetConst(r)) | int_set ^^ (s => IntSetConst(s)) lazy val array_const: Parser[ArrayConst] = - "[" ~> repsep(expr, ",") <~ "]" ^^ (elems => ArrayConst(elems.toIndexedSeq)) + "[" ~> repsep(expr, ",") <~ "]" ^^ (elems => ArrayConst(elems.toVector)) lazy val array_access: Parser[ArrayAccess] = identifier ~ ("[" ~> expr <~ "]") ^^ { case id ~ idx => ArrayAccess(id, idx) diff --git a/src/test/yuck/constraints/test/OptimizationGoalTrackerTest.scala b/src/test/yuck/constraints/test/OptimizationGoalTrackerTest.scala index 7a9dc0e..8e75b39 100644 --- a/src/test/yuck/constraints/test/OptimizationGoalTrackerTest.scala +++ b/src/test/yuck/constraints/test/OptimizationGoalTrackerTest.scala @@ -23,7 +23,7 @@ class OptimizationGoalTrackerTest extends UnitTest { val dy = IntegerRange(IntegerValue(0), IntegerValue(100)) val x = new IntegerVariable(space.nextVariableId(), "x", dx) val y = new IntegerVariable(space.nextVariableId(), "y", dy) - val axs = immutable.IndexedSeq(new AX(Three, x), new AX(IntegerValue(-2), y)) + val axs = Vector(new AX(Three, x), new AX(IntegerValue(-2), y)) val c = new OptimizationGoalTracker(space.nextConstraintId(), null, OptimizationMode.Min, axs, d) space .post(c) @@ -75,7 +75,7 @@ class OptimizationGoalTrackerTest extends UnitTest { val dy = IntegerRange(IntegerValue(-10), IntegerValue(50)) val x = new IntegerVariable(space.nextVariableId(), "x", dx) val y = new IntegerVariable(space.nextVariableId(), "y", dy) - val axs = immutable.IndexedSeq(new AX(Three, x), new AX(IntegerValue(-2), y)) + val axs = Vector(new AX(Three, x), new AX(IntegerValue(-2), y)) val c = new OptimizationGoalTracker(space.nextConstraintId(), null, OptimizationMode.Max, axs, d) space .post(c) diff --git a/src/test/yuck/core/test/IntegerDomainTestHelper.scala b/src/test/yuck/core/test/IntegerDomainTestHelper.scala index a1b6a94..338066c 100644 --- a/src/test/yuck/core/test/IntegerDomainTestHelper.scala +++ b/src/test/yuck/core/test/IntegerDomainTestHelper.scala @@ -330,7 +330,7 @@ final class IntegerDomainTestHelper assertEq(e.lb, if (d.hasUb) d.ub.negated else null) assertEq(e.ub, if (d.hasLb) d.lb.negated else null) case d: IntegerRangeList => - assertEq(e, IntegerRangeList(d.ranges.reverseIterator.map(_.mirrored).toIndexedSeq)) + assertEq(e, IntegerRangeList(d.ranges.reverseIterator.map(_.mirrored).toVector)) } } } diff --git a/src/test/yuck/core/test/SpaceTest.scala b/src/test/yuck/core/test/SpaceTest.scala index 6f30e14..1de4d43 100644 --- a/src/test/yuck/core/test/SpaceTest.scala +++ b/src/test/yuck/core/test/SpaceTest.scala @@ -435,7 +435,7 @@ final class SpaceTest extends UnitTest { // generate and perform m moves val neighbourhood = new RandomReassignmentGenerator( - space, space.searchVariables.toIndexedSeq, randomGenerator, moveSizeDistribution, None, None) + space, space.searchVariables.toVector, randomGenerator, moveSizeDistribution, None, None) for (i <- 1 to m) { // generate move and consult space val move = neighbourhood.nextMove diff --git a/src/test/yuck/test/Queens.scala b/src/test/yuck/test/Queens.scala index e1638e0..23368f8 100644 --- a/src/test/yuck/test/Queens.scala +++ b/src/test/yuck/test/Queens.scala @@ -40,12 +40,12 @@ final class Queens(val n: Int) extends IntegrationTest { space.post(new Plus(space.nextConstraintId(), null, rows(col), iVar, rowsPlusI(col))) } val rowConflicts = new BooleanVariable(space.nextVariableId(), "rowConflicts", CompleteBooleanDomain) - val rowConstraint = new Alldistinct(space.nextConstraintId(), null, rows.toIndexedSeq, rowConflicts) + val rowConstraint = new Alldistinct(space.nextConstraintId(), null, rows.toVector, rowConflicts) space.post(rowConstraint) val diagonalConflicts1 = new BooleanVariable(space.nextVariableId(), "diagonalConflicts1", CompleteBooleanDomain) - space.post(new Alldistinct(space.nextConstraintId(), null, rowsMinusI.toIndexedSeq, diagonalConflicts1)) + space.post(new Alldistinct(space.nextConstraintId(), null, rowsMinusI.toVector, diagonalConflicts1)) val diagonalConflicts2 = new BooleanVariable(space.nextVariableId(), "diagonalConflicts2", CompleteBooleanDomain) - space.post(new Alldistinct(space.nextConstraintId(), null, rowsPlusI.toIndexedSeq, diagonalConflicts2)) + space.post(new Alldistinct(space.nextConstraintId(), null, rowsPlusI.toVector, diagonalConflicts2)) val conflicts = new BooleanVariable(space.nextVariableId(), "conflicts", CompleteBooleanDomain) space.post( new Conjunction( diff --git a/src/test/yuck/test/SendMoreMoney.scala b/src/test/yuck/test/SendMoreMoney.scala index 79ed56d..8a1edef 100644 --- a/src/test/yuck/test/SendMoreMoney.scala +++ b/src/test/yuck/test/SendMoreMoney.scala @@ -54,7 +54,7 @@ final class SendMoreMoney extends IntegrationTest { val numberOfMissingValues = new BooleanVariable(space.nextVariableId(), "numberOfMissingValues", CompleteBooleanDomain) space.post( - new Alldistinct(space.nextConstraintId(), null, vars.toIndexedSeq, numberOfMissingValues)) + new Alldistinct(space.nextConstraintId(), null, vars.toVector, numberOfMissingValues)) val LHS = List((1000, S), (100, E), (10, N), (1, D), (1000, M), (100, O), (10, R), (1, E)) val RHS = List((10000, M), (1000, O), (100, N), (10, E), (1, Y)) val lhs = new IntegerVariable(space.nextVariableId(), "lhs", CompleteIntegerRange) @@ -108,7 +108,7 @@ final class SendMoreMoney extends IntegrationTest { "SA", space, createAnnealingSchedule(space.searchVariables.size, randomGenerator.nextGen()), - new SimpleRandomReassignmentGenerator(space, space.searchVariables.toIndexedSeq, randomGenerator.nextGen()), + new SimpleRandomReassignmentGenerator(space, space.searchVariables.toVector, randomGenerator.nextGen()), randomGenerator.nextGen(), new SatisfactionObjective(costs), None, diff --git a/src/test/yuck/test/SendMostMoney.scala b/src/test/yuck/test/SendMostMoney.scala index 85cf5c3..5581b09 100644 --- a/src/test/yuck/test/SendMostMoney.scala +++ b/src/test/yuck/test/SendMostMoney.scala @@ -109,7 +109,7 @@ final class SendMostMoney extends IntegrationTest { solverName, space, createAnnealingSchedule(space.searchVariables.size, randomGenerator.nextGen()), - new SimpleRandomReassignmentGenerator(space, space.searchVariables.toIndexedSeq, randomGenerator.nextGen()), + new SimpleRandomReassignmentGenerator(space, space.searchVariables.toVector, randomGenerator.nextGen()), randomGenerator.nextGen(), new HierarchicalObjective( List(new SatisfactionObjective(costs),