Skip to content

Commit c671912

Browse files
committed
Initial move impl (does not work yet)
1 parent ec43ed2 commit c671912

17 files changed

+358
-58
lines changed

core/src/main/java/ai/timefold/solver/core/impl/move/director/MoveDirector.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package ai.timefold.solver.core.impl.move.director;
22

3-
import java.util.List;
4-
import java.util.Objects;
5-
import java.util.function.BiFunction;
6-
73
import ai.timefold.solver.core.api.score.Score;
84
import ai.timefold.solver.core.impl.domain.entity.descriptor.EntityDescriptor;
95
import ai.timefold.solver.core.impl.domain.solution.descriptor.DefaultPlanningListVariableMetaModel;
@@ -22,10 +18,13 @@
2218
import ai.timefold.solver.core.preview.api.domain.metamodel.PlanningVariableMetaModel;
2319
import ai.timefold.solver.core.preview.api.move.Move;
2420
import ai.timefold.solver.core.preview.api.move.Rebaser;
25-
2621
import org.jspecify.annotations.NullMarked;
2722
import org.jspecify.annotations.Nullable;
2823

24+
import java.util.List;
25+
import java.util.Objects;
26+
import java.util.function.BiFunction;
27+
2928
@NullMarked
3029
public sealed class MoveDirector<Solution_, Score_ extends Score<Score_>>
3130
implements InnerMutableSolutionView<Solution_>, Rebaser
@@ -185,6 +184,11 @@ public final <Entity_, Value_> Value_ getValue(PlanningVariableMetaModel<Solutio
185184
return extractVariableDescriptor(variableMetaModel).getValue(entity);
186185
}
187186

187+
@Override
188+
public <Entity_, Value_> int countValues(PlanningListVariableMetaModel<Solution_, Entity_, Value_> variableMetaModel, Entity_ entity) {
189+
return extractVariableDescriptor(variableMetaModel).getValue(entity).size();
190+
}
191+
188192
@SuppressWarnings("unchecked")
189193
@Override
190194
public final <Entity_, Value_> Value_ getValueAtIndex(

core/src/main/java/ai/timefold/solver/core/impl/move/streams/DefaultMoveStreamFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public DefaultMoveStreamFactory(SolutionDescriptor<Solution_> solutionDescriptor
3535

3636
public DefaultMoveStreamSession<Solution_> createSession(SessionContext<Solution_> context) {
3737
var session = datasetSessionFactory.buildSession(context);
38-
return new DefaultMoveStreamSession<>(session, context.workingSolution());
38+
return new DefaultMoveStreamSession<>(session, context.solutionView());
3939
}
4040

4141
@Override

core/src/main/java/ai/timefold/solver/core/impl/move/streams/DefaultMoveStreamSession.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
package ai.timefold.solver.core.impl.move.streams;
22

3-
import java.util.Objects;
4-
53
import ai.timefold.solver.core.impl.move.streams.dataset.BiDataset;
64
import ai.timefold.solver.core.impl.move.streams.dataset.BiDatasetInstance;
75
import ai.timefold.solver.core.impl.move.streams.dataset.DatasetSession;
86
import ai.timefold.solver.core.impl.move.streams.dataset.UniDataset;
97
import ai.timefold.solver.core.impl.move.streams.dataset.UniDatasetInstance;
108
import ai.timefold.solver.core.impl.move.streams.maybeapi.stream.MoveStreamSession;
11-
9+
import ai.timefold.solver.core.preview.api.move.SolutionView;
1210
import org.jspecify.annotations.NullMarked;
1311

12+
import java.util.Objects;
13+
1414
@NullMarked
1515
public final class DefaultMoveStreamSession<Solution_>
1616
implements MoveStreamSession<Solution_>, AutoCloseable {
1717

1818
private final DatasetSession<Solution_> datasetSession;
19-
private final Solution_ workingSolution;
19+
private final SolutionView<Solution_> solutionView;
2020

21-
public DefaultMoveStreamSession(DatasetSession<Solution_> datasetSession, Solution_ workingSolution) {
21+
public DefaultMoveStreamSession(DatasetSession<Solution_> datasetSession, SolutionView<Solution_> solutionView) {
2222
this.datasetSession = Objects.requireNonNull(datasetSession);
23-
this.workingSolution = Objects.requireNonNull(workingSolution);
23+
this.solutionView = Objects.requireNonNull(solutionView);
2424
}
2525

2626
public <A> UniDatasetInstance<Solution_, A> getDatasetInstance(UniDataset<Solution_, A> dataset) {
@@ -47,8 +47,8 @@ public void settle() {
4747
datasetSession.settle();
4848
}
4949

50-
public Solution_ getWorkingSolution() {
51-
return workingSolution;
50+
public SolutionView<Solution_> getSolutionView() {
51+
return solutionView;
5252
}
5353

5454
@Override

core/src/main/java/ai/timefold/solver/core/impl/move/streams/FromBiUniMoveProducer.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
package ai.timefold.solver.core.impl.move.streams;
22

3-
import java.util.Iterator;
4-
import java.util.NoSuchElementException;
5-
import java.util.Objects;
6-
import java.util.Random;
7-
import java.util.Set;
8-
import java.util.function.Supplier;
9-
103
import ai.timefold.solver.core.impl.bavet.common.tuple.BiTuple;
114
import ai.timefold.solver.core.impl.move.streams.dataset.AbstractDataStream;
125
import ai.timefold.solver.core.impl.move.streams.dataset.BiDataset;
136
import ai.timefold.solver.core.impl.move.streams.maybeapi.stream.BiMoveConstructor;
147
import ai.timefold.solver.core.impl.move.streams.maybeapi.stream.MoveStreamSession;
158
import ai.timefold.solver.core.preview.api.move.Move;
16-
9+
import ai.timefold.solver.core.preview.api.move.SolutionView;
1710
import org.jspecify.annotations.NullMarked;
1811
import org.jspecify.annotations.Nullable;
1912

13+
import java.util.Iterator;
14+
import java.util.NoSuchElementException;
15+
import java.util.Objects;
16+
import java.util.Random;
17+
import java.util.Set;
18+
import java.util.function.Supplier;
19+
2020
@NullMarked
2121
public final class FromBiUniMoveProducer<Solution_, A, B> implements InnerMoveProducer<Solution_> {
2222

@@ -42,7 +42,7 @@ public void collectActiveDataStreams(Set<AbstractDataStream<Solution_>> activeDa
4242
private final class InnerMoveIterator implements Iterator<Move<Solution_>> {
4343

4444
private final IteratorSupplier<A, B> iteratorSupplier;
45-
private final Solution_ solution;
45+
private final SolutionView<Solution_> solutionView;
4646

4747
// Fields required for iteration.
4848
private @Nullable Move<Solution_> nextMove;
@@ -51,13 +51,13 @@ private final class InnerMoveIterator implements Iterator<Move<Solution_>> {
5151
public InnerMoveIterator(DefaultMoveStreamSession<Solution_> moveStreamSession) {
5252
var aInstance = moveStreamSession.getDatasetInstance(aDataset);
5353
this.iteratorSupplier = aInstance::iterator;
54-
this.solution = moveStreamSession.getWorkingSolution();
54+
this.solutionView = moveStreamSession.getSolutionView();
5555
}
5656

5757
public InnerMoveIterator(DefaultMoveStreamSession<Solution_> moveStreamSession, Random random) {
5858
var aInstance = moveStreamSession.getDatasetInstance(aDataset);
5959
this.iteratorSupplier = () -> aInstance.iterator(random);
60-
this.solution = moveStreamSession.getWorkingSolution();
60+
this.solutionView = moveStreamSession.getSolutionView();
6161
}
6262

6363
@Override
@@ -78,7 +78,7 @@ public boolean hasNext() {
7878
}
7979

8080
var tuple = iterator.next();
81-
nextMove = moveConstructor.apply(solution, tuple.factA, tuple.factB);
81+
nextMove = moveConstructor.apply(solutionView, tuple.factA, tuple.factB);
8282
return true;
8383
}
8484

core/src/main/java/ai/timefold/solver/core/impl/move/streams/FromUniBiMoveProducer.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
package ai.timefold.solver.core.impl.move.streams;
22

3-
import java.util.Iterator;
4-
import java.util.NoSuchElementException;
5-
import java.util.Objects;
6-
import java.util.Random;
7-
import java.util.Set;
8-
import java.util.function.BiPredicate;
9-
import java.util.function.Supplier;
10-
113
import ai.timefold.solver.core.impl.bavet.common.tuple.UniTuple;
124
import ai.timefold.solver.core.impl.move.streams.dataset.AbstractDataStream;
135
import ai.timefold.solver.core.impl.move.streams.dataset.UniDataset;
146
import ai.timefold.solver.core.impl.move.streams.maybeapi.stream.BiMoveConstructor;
157
import ai.timefold.solver.core.impl.move.streams.maybeapi.stream.MoveStreamSession;
168
import ai.timefold.solver.core.preview.api.move.Move;
17-
9+
import ai.timefold.solver.core.preview.api.move.SolutionView;
1810
import org.jspecify.annotations.NullMarked;
1911
import org.jspecify.annotations.Nullable;
2012

13+
import java.util.Iterator;
14+
import java.util.NoSuchElementException;
15+
import java.util.Objects;
16+
import java.util.Random;
17+
import java.util.Set;
18+
import java.util.function.BiPredicate;
19+
import java.util.function.Supplier;
20+
2121
@NullMarked
2222
public final class FromUniBiMoveProducer<Solution_, A, B> implements InnerMoveProducer<Solution_> {
2323

@@ -49,7 +49,7 @@ private final class BiMoveIterator implements Iterator<Move<Solution_>> {
4949

5050
private final IteratorSupplier<A> aIteratorSupplier;
5151
private final IteratorSupplier<B> bIteratorSupplier;
52-
private final Solution_ solution;
52+
private final SolutionView<Solution_> solutionView;
5353

5454
// Fields required for iteration.
5555
private @Nullable Move<Solution_> nextMove;
@@ -62,15 +62,15 @@ public BiMoveIterator(DefaultMoveStreamSession<Solution_> moveStreamSession) {
6262
this.aIteratorSupplier = aInstance::iterator;
6363
var bInstance = moveStreamSession.getDatasetInstance(bDataset);
6464
this.bIteratorSupplier = bInstance::iterator;
65-
this.solution = moveStreamSession.getWorkingSolution();
65+
this.solutionView = moveStreamSession.getSolutionView();
6666
}
6767

6868
public BiMoveIterator(DefaultMoveStreamSession<Solution_> moveStreamSession, Random random) {
6969
var aInstance = moveStreamSession.getDatasetInstance(aDataset);
7070
this.aIteratorSupplier = () -> aInstance.iterator(random);
7171
var bInstance = moveStreamSession.getDatasetInstance(bDataset);
7272
this.bIteratorSupplier = () -> bInstance.iterator(random);
73-
this.solution = moveStreamSession.getWorkingSolution();
73+
this.solutionView = moveStreamSession.getSolutionView();
7474
}
7575

7676
@Override
@@ -101,7 +101,7 @@ public boolean hasNext() {
101101
// Check if this pair passes the filter...
102102
if (filter.test(currentA, currentB)) {
103103
// ... and create the next move.
104-
nextMove = moveConstructor.apply(solution, currentA, currentB);
104+
nextMove = moveConstructor.apply(solutionView, currentA, currentB);
105105
return true;
106106
}
107107
}

core/src/main/java/ai/timefold/solver/core/impl/move/streams/dataset/AbstractBiDataStream.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package ai.timefold.solver.core.impl.move.streams.dataset;
22

33
import ai.timefold.solver.core.impl.move.streams.maybeapi.BiDataFilter;
4+
import ai.timefold.solver.core.impl.move.streams.maybeapi.BiDataMapper;
45
import ai.timefold.solver.core.impl.move.streams.maybeapi.stream.BiDataStream;
56

7+
import ai.timefold.solver.core.impl.move.streams.maybeapi.stream.UniDataStream;
68
import org.jspecify.annotations.NullMarked;
79
import org.jspecify.annotations.Nullable;
810

@@ -24,6 +26,21 @@ public final BiDataStream<Solution_, A, B> filter(BiDataFilter<Solution_, A, B>
2426
return shareAndAddChild(new FilterBiDataStream<>(dataStreamFactory, this, filter));
2527
}
2628

29+
@Override
30+
public <ResultA_> UniDataStream<Solution_, ResultA_> map(BiDataMapper<Solution_, A, B, ResultA_> mapping) {
31+
return null;
32+
}
33+
34+
@Override
35+
public <ResultA_, ResultB_> BiDataStream<Solution_, ResultA_, ResultB_> map(BiDataMapper<Solution_, A, B, ResultA_> mappingA, BiDataMapper<Solution_, A, B, ResultB_> mappingB) {
36+
return null;
37+
}
38+
39+
@Override
40+
public BiDataStream<Solution_, A, B> distinct() {
41+
return null;
42+
}
43+
2744
public BiDataset<Solution_, A, B> createDataset() {
2845
var stream = shareAndAddChild(new TerminalBiDataStream<>(dataStreamFactory, this));
2946
return stream.getDataset();

core/src/main/java/ai/timefold/solver/core/impl/move/streams/dataset/AbstractUniDataStream.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import ai.timefold.solver.core.impl.move.streams.dataset.joiner.BiDataJoinerComber;
55
import ai.timefold.solver.core.impl.move.streams.maybeapi.BiDataJoiner;
66
import ai.timefold.solver.core.impl.move.streams.maybeapi.UniDataFilter;
7+
import ai.timefold.solver.core.impl.move.streams.maybeapi.UniDataMapper;
78
import ai.timefold.solver.core.impl.move.streams.maybeapi.stream.BiDataStream;
89
import ai.timefold.solver.core.impl.move.streams.maybeapi.stream.UniDataStream;
910

@@ -86,6 +87,21 @@ private <B> UniDataStream<Solution_, A> ifExistsOrNot(boolean shouldExist, UniDa
8687
joinerComber.mergedJoiner(), joinerComber.mergedFiltering()), childStreamList::add);
8788
}
8889

90+
@Override
91+
public <ResultA_> UniDataStream<Solution_, ResultA_> map(UniDataMapper<Solution_, A, ResultA_> mapping) {
92+
return null;
93+
}
94+
95+
@Override
96+
public <ResultA_, ResultB_> BiDataStream<Solution_, ResultA_, ResultB_> map(UniDataMapper<Solution_, A, ResultA_> mappingA, UniDataMapper<Solution_, A, ResultB_> mappingB) {
97+
return null;
98+
}
99+
100+
@Override
101+
public UniDataStream<Solution_, A> distinct() {
102+
return null;
103+
}
104+
89105
public UniDataset<Solution_, A> createDataset() {
90106
var stream = shareAndAddChild(new TerminalUniDataStream<>(dataStreamFactory, this));
91107
return stream.getDataset();
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package ai.timefold.solver.core.impl.move.streams.maybeapi;
2+
3+
import ai.timefold.solver.core.api.function.TriFunction;
4+
import ai.timefold.solver.core.impl.move.streams.maybeapi.stream.BiDataStream;
5+
import ai.timefold.solver.core.preview.api.move.SolutionView;
6+
import org.jspecify.annotations.NullMarked;
7+
import org.jspecify.annotations.Nullable;
8+
9+
import java.util.function.BiFunction;
10+
11+
/**
12+
* A mapping function that can be applied to {@link BiDataStream} to transform data,
13+
* optionally using {@link SolutionView} to query for solution state.
14+
*
15+
* @param <Solution_> the type of the solution
16+
* @param <A> the type of the first parameter
17+
* @param <B> the type of the second parameter
18+
*/
19+
@NullMarked
20+
public interface BiDataMapper<Solution_, A, B, Result_> extends TriFunction<SolutionView<Solution_>, A, B, Result_> {
21+
22+
@Override
23+
Result_ apply(SolutionView<Solution_> solutionSolutionView, @Nullable A a, @Nullable B b);
24+
25+
default BiFunction<A, B, Result_> toBiFunction(SolutionView<Solution_> solutionView) {
26+
return (a, b) -> apply(solutionView, a, b);
27+
}
28+
29+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package ai.timefold.solver.core.impl.move.streams.maybeapi;
2+
3+
import ai.timefold.solver.core.impl.move.streams.maybeapi.stream.UniDataStream;
4+
import ai.timefold.solver.core.preview.api.move.SolutionView;
5+
import org.jspecify.annotations.NullMarked;
6+
import org.jspecify.annotations.Nullable;
7+
8+
import java.util.function.BiFunction;
9+
import java.util.function.Function;
10+
11+
/**
12+
* A mapping function that can be applied to {@link UniDataStream} to transform data,
13+
* optionally using {@link SolutionView} to query for solution state.
14+
*
15+
* @param <Solution_> the type of the solution
16+
* @param <A> the type of the first parameter
17+
*/
18+
@NullMarked
19+
public interface UniDataMapper<Solution_, A, Result_> extends BiFunction<SolutionView<Solution_>, A, Result_> {
20+
21+
@Override
22+
Result_ apply(SolutionView<Solution_> solutionSolutionView, @Nullable A a);
23+
24+
default Function<A, Result_> toFunction(SolutionView<Solution_> solutionView) {
25+
return a -> apply(solutionView, a);
26+
}
27+
28+
}

core/src/main/java/ai/timefold/solver/core/impl/move/streams/maybeapi/generic/move/ListUnassignMove.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package ai.timefold.solver.core.impl.move.streams.maybeapi.generic.move;
22

3-
import java.util.Collection;
4-
import java.util.Collections;
5-
import java.util.List;
6-
import java.util.Objects;
7-
83
import ai.timefold.solver.core.preview.api.domain.metamodel.PlanningListVariableMetaModel;
94
import ai.timefold.solver.core.preview.api.domain.metamodel.VariableMetaModel;
105
import ai.timefold.solver.core.preview.api.move.Move;
116
import ai.timefold.solver.core.preview.api.move.MutableSolutionView;
127
import ai.timefold.solver.core.preview.api.move.Rebaser;
13-
148
import org.jspecify.annotations.NonNull;
159

10+
import java.util.Collection;
11+
import java.util.Collections;
12+
import java.util.List;
13+
import java.util.Objects;
14+
1615
public final class ListUnassignMove<Solution_, Entity_, Value_> extends AbstractMove<Solution_> {
1716

1817
private final PlanningListVariableMetaModel<Solution_, Entity_, Value_> variableMetaModel;

0 commit comments

Comments
 (0)