aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-reasoning-scope/src/test/java
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-09-03 14:11:29 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-09-03 14:11:29 +0200
commit5ab558ad2d7c3a8e47bdd21b1dbe7190d430125c (patch)
treee9f10f5a8450aba6a151ef42ac7d40a1e986f17e /subprojects/store-reasoning-scope/src/test/java
parentchore(build): replce deprecated Gradle API use (diff)
downloadrefinery-5ab558ad2d7c3a8e47bdd21b1dbe7190d430125c.tar.gz
refinery-5ab558ad2d7c3a8e47bdd21b1dbe7190d430125c.tar.zst
refinery-5ab558ad2d7c3a8e47bdd21b1dbe7190d430125c.zip
feat: type scope propagator
Diffstat (limited to 'subprojects/store-reasoning-scope/src/test/java')
-rw-r--r--subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MPSolverTest.java52
-rw-r--r--subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MultiObjectTest.java206
-rw-r--r--subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/internal/RoundingUtilTest.java69
3 files changed, 327 insertions, 0 deletions
diff --git a/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MPSolverTest.java b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MPSolverTest.java
new file mode 100644
index 00000000..c9745d22
--- /dev/null
+++ b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MPSolverTest.java
@@ -0,0 +1,52 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.scope;
7
8import com.google.ortools.Loader;
9import com.google.ortools.linearsolver.MPSolver;
10import org.junit.jupiter.api.BeforeAll;
11import org.junit.jupiter.api.Test;
12
13import static org.hamcrest.MatcherAssert.assertThat;
14import static org.hamcrest.Matchers.closeTo;
15import static org.hamcrest.Matchers.is;
16
17class MPSolverTest {
18 @BeforeAll
19 static void beforeAll() {
20 Loader.loadNativeLibraries();
21 }
22
23 @Test
24 void updateProblemTest() {
25 var solver = MPSolver.createSolver("GLOP");
26 var x = solver.makeNumVar(0, Double.POSITIVE_INFINITY, "x");
27 var y = solver.makeNumVar(0, 1, "y");
28 var constraint = solver.makeConstraint(5, 5);
29 constraint.setCoefficient(x, 1);
30 constraint.setCoefficient(y, 1);
31 var objective = solver.objective();
32
33 objective.setCoefficient(x, 1);
34 objective.setMinimization();
35 assertThat(solver.solve(), is(MPSolver.ResultStatus.OPTIMAL));
36 assertThat(objective.value(), closeTo(4, 0.01));
37
38 objective.setMaximization();
39 assertThat(solver.solve(), is(MPSolver.ResultStatus.OPTIMAL));
40 assertThat(objective.value(), closeTo(5, 0.01));
41
42 objective.setCoefficient(x, 0);
43 objective.setCoefficient(y, 1);
44 objective.setMinimization();
45 assertThat(solver.solve(), is(MPSolver.ResultStatus.OPTIMAL));
46 assertThat(objective.value(), closeTo(0, 0.01));
47
48 objective.setMaximization();
49 assertThat(solver.solve(), is(MPSolver.ResultStatus.OPTIMAL));
50 assertThat(objective.value(), closeTo(1, 0.01));
51 }
52}
diff --git a/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MultiObjectTest.java b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MultiObjectTest.java
new file mode 100644
index 00000000..42ce2f56
--- /dev/null
+++ b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/MultiObjectTest.java
@@ -0,0 +1,206 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.scope;
7
8import org.junit.jupiter.api.BeforeEach;
9import org.junit.jupiter.api.Test;
10import tools.refinery.store.model.Interpretation;
11import tools.refinery.store.model.Model;
12import tools.refinery.store.model.ModelStore;
13import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
14import tools.refinery.store.reasoning.ReasoningAdapter;
15import tools.refinery.store.reasoning.ReasoningStoreAdapter;
16import tools.refinery.store.reasoning.refinement.RefinementResult;
17import tools.refinery.store.reasoning.representation.PartialRelation;
18import tools.refinery.store.reasoning.seed.ModelSeed;
19import tools.refinery.store.reasoning.translator.PartialRelationTranslator;
20import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator;
21import tools.refinery.store.representation.Symbol;
22import tools.refinery.store.representation.TruthValue;
23import tools.refinery.store.representation.cardinality.CardinalityInterval;
24import tools.refinery.store.representation.cardinality.CardinalityIntervals;
25import tools.refinery.store.tuple.Tuple;
26
27import static org.hamcrest.MatcherAssert.assertThat;
28import static org.hamcrest.Matchers.is;
29
30class MultiObjectTest {
31 private static final PartialRelation person = new PartialRelation("Person", 1);
32
33 private ModelStore store;
34 private Model model;
35 private Interpretation<CardinalityInterval> countStorage;
36
37 @BeforeEach
38 void beforeEach() {
39 store = ModelStore.builder()
40 .with(ViatraModelQueryAdapter.builder())
41 .with(ReasoningAdapter.builder())
42 .with(new MultiObjectTranslator())
43 .with(PartialRelationTranslator.of(person)
44 .symbol(Symbol.of("Person", 1, TruthValue.class, TruthValue.FALSE)))
45 .with(ScopePropagatorAdapter.builder()
46 .scope(person, CardinalityIntervals.between(5, 15)))
47 .build();
48 model = null;
49 countStorage = null;
50 }
51
52 @Test
53 void oneMultiObjectSatisfiableTest() {
54 createModel(ModelSeed.builder(4)
55 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
56 .reducedValue(CardinalityIntervals.ONE)
57 .put(Tuple.of(0), CardinalityIntervals.SET))
58 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
59 .build());
60 assertThat(propagate(), is(RefinementResult.REFINED));
61 assertThat(countStorage.get(Tuple.of(0)), is(CardinalityIntervals.between(2, 12)));
62 }
63
64 @Test
65 void oneMultiObjectExistingBoundSatisfiableTest() {
66 createModel(ModelSeed.builder(4)
67 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
68 .reducedValue(CardinalityIntervals.ONE)
69 .put(Tuple.of(0), CardinalityIntervals.between(5, 20)))
70 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
71 .build());
72 assertThat(propagate(), is(RefinementResult.REFINED));
73 assertThat(countStorage.get(Tuple.of(0)), is(CardinalityIntervals.between(5, 12)));
74 }
75
76 @Test
77 void oneMultiObjectUnsatisfiableUpperTest() {
78 createModel(ModelSeed.builder(21)
79 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
80 .reducedValue(CardinalityIntervals.ONE)
81 .put(Tuple.of(0), CardinalityIntervals.SET))
82 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
83 .build());
84 assertThat(propagate(), is(RefinementResult.REJECTED));
85 }
86
87 @Test
88 void noMultiObjectSatisfiableTest() {
89 createModel(ModelSeed.builder(10)
90 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder.reducedValue(CardinalityIntervals.ONE))
91 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
92 .build());
93 assertThat(propagate(), is(RefinementResult.UNCHANGED));
94 }
95
96 @Test
97 void noMultiObjectUnsatisfiableTest() {
98 createModel(ModelSeed.builder(2)
99 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder.reducedValue(CardinalityIntervals.ONE))
100 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
101 .build());
102 assertThat(propagate(), is(RefinementResult.REJECTED));
103 }
104
105 @Test
106 void oneMultiObjectExistingBoundUnsatisfiableLowerTest() {
107 createModel(ModelSeed.builder(4)
108 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
109 .reducedValue(CardinalityIntervals.ONE)
110 .put(Tuple.of(0), CardinalityIntervals.atLeast(20)))
111 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
112 .build());
113 assertThat(propagate(), is(RefinementResult.REJECTED));
114 }
115
116 @Test
117 void oneMultiObjectExistingBoundUnsatisfiableUpperTest() {
118 createModel(ModelSeed.builder(4)
119 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
120 .reducedValue(CardinalityIntervals.ONE)
121 .put(Tuple.of(0), CardinalityIntervals.atMost(1)))
122 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
123 .build());
124 assertThat(propagate(), is(RefinementResult.REJECTED));
125 }
126
127 @Test
128 void twoMultiObjectsSatisfiableTest() {
129 createModel(ModelSeed.builder(5)
130 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
131 .reducedValue(CardinalityIntervals.ONE)
132 .put(Tuple.of(0), CardinalityIntervals.SET)
133 .put(Tuple.of(1), CardinalityIntervals.SET))
134 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
135 .build());
136 assertThat(propagate(), is(RefinementResult.REFINED));
137 assertThat(countStorage.get(Tuple.of(0)), is(CardinalityIntervals.atMost(12)));
138 assertThat(countStorage.get(Tuple.of(1)), is(CardinalityIntervals.atMost(12)));
139 }
140
141 @Test
142 void twoMultiObjectsExistingBoundSatisfiableTest() {
143 createModel(ModelSeed.builder(5)
144 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
145 .reducedValue(CardinalityIntervals.ONE)
146 .put(Tuple.of(0), CardinalityIntervals.between(7, 20))
147 .put(Tuple.of(1), CardinalityIntervals.atMost(11)))
148 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
149 .build());
150 assertThat(propagate(), is(RefinementResult.REFINED));
151 assertThat(countStorage.get(Tuple.of(0)), is(CardinalityIntervals.between(7, 12)));
152 assertThat(countStorage.get(Tuple.of(1)), is(CardinalityIntervals.atMost(5)));
153 }
154
155 @Test
156 void twoMultiObjectsExistingBoundUnsatisfiableUpperTest() {
157 createModel(ModelSeed.builder(5)
158 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
159 .reducedValue(CardinalityIntervals.ONE)
160 .put(Tuple.of(0), CardinalityIntervals.between(7, 20))
161 .put(Tuple.of(1), CardinalityIntervals.exactly(11)))
162 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
163 .build());
164 assertThat(propagate(), is(RefinementResult.REJECTED));
165 }
166
167 @Test
168 void twoMultiObjectsExistingBoundUnsatisfiableLowerTest() {
169 createModel(ModelSeed.builder(3)
170 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
171 .reducedValue(CardinalityIntervals.ONE)
172 .put(Tuple.of(0), CardinalityIntervals.LONE)
173 .put(Tuple.of(1), CardinalityIntervals.atMost(2)))
174 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
175 .build());
176 assertThat(propagate(), is(RefinementResult.REJECTED));
177 }
178
179 @Test
180 void multiToSingleTest() {
181 createModel(ModelSeed.builder(5)
182 .seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder
183 .reducedValue(CardinalityIntervals.ONE)
184 .put(Tuple.of(0), CardinalityIntervals.LONE)
185 .put(Tuple.of(1), CardinalityIntervals.SET))
186 .seed(person, builder -> builder.reducedValue(TruthValue.TRUE))
187 .build());
188 assertThat(propagate(), is(RefinementResult.REFINED));
189 assertThat(countStorage.get(Tuple.of(0)), is(CardinalityIntervals.LONE));
190 assertThat(countStorage.get(Tuple.of(1)), is(CardinalityIntervals.between(1, 12)));
191 countStorage.put(Tuple.of(0), CardinalityIntervals.ONE);
192 assertThat(propagate(), is(RefinementResult.REFINED));
193 assertThat(countStorage.get(Tuple.of(1)), is(CardinalityIntervals.between(1, 11)));
194 countStorage.put(Tuple.of(1), CardinalityIntervals.ONE);
195 assertThat(propagate(), is(RefinementResult.UNCHANGED));
196 }
197
198 private void createModel(ModelSeed modelSeed) {
199 model = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(modelSeed);
200 countStorage = model.getInterpretation(MultiObjectTranslator.COUNT_STORAGE);
201 }
202
203 private RefinementResult propagate() {
204 return model.getAdapter(ScopePropagatorAdapter.class).propagate();
205 }
206}
diff --git a/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/internal/RoundingUtilTest.java b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/internal/RoundingUtilTest.java
new file mode 100644
index 00000000..9daed660
--- /dev/null
+++ b/subprojects/store-reasoning-scope/src/test/java/tools/refinery/store/reasoning/scope/internal/RoundingUtilTest.java
@@ -0,0 +1,69 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.scope.internal;
7
8import org.junit.jupiter.params.ParameterizedTest;
9import org.junit.jupiter.params.provider.Arguments;
10import org.junit.jupiter.params.provider.MethodSource;
11
12import java.util.stream.Stream;
13
14import static org.hamcrest.MatcherAssert.assertThat;
15import static org.hamcrest.Matchers.is;
16
17class RoundingUtilTest {
18 @ParameterizedTest
19 @MethodSource
20 void roundUpTest(double value, int expected) {
21 int actual = RoundingUtil.roundUp(value);
22 assertThat(actual, is(expected));
23 }
24
25 static Stream<Arguments> roundUpTest() {
26 return Stream.of(
27 Arguments.of(0.0, 0),
28 Arguments.of(-0.0, 0),
29 Arguments.of(-0.9, 0),
30 Arguments.of(-2, 0),
31 Arguments.of(0.009, 0),
32 Arguments.of(0.011, 1),
33 Arguments.of(0.1, 1),
34 Arguments.of(0.991, 1),
35 Arguments.of(1, 1),
36 Arguments.of(1.009, 1),
37 Arguments.of(1.011, 2),
38 Arguments.of(1.5, 2),
39 Arguments.of(2, 2),
40 Arguments.of(100.5, 101)
41 );
42 }
43
44 @ParameterizedTest
45 @MethodSource
46 void roundDownTest(double value, int expected) {
47 int actual = RoundingUtil.roundDown(value);
48 assertThat(actual, is(expected));
49 }
50
51 static Stream<Arguments> roundDownTest() {
52 return Stream.of(
53 Arguments.of(0.0, 0),
54 Arguments.of(-0.0, 0),
55 Arguments.of(-0.9, 0),
56 Arguments.of(-2, 0),
57 Arguments.of(0.989, 0),
58 Arguments.of(0.991, 1),
59 Arguments.of(1, 1),
60 Arguments.of(1.5, 1),
61 Arguments.of(1.009, 1),
62 Arguments.of(1.989, 1),
63 Arguments.of(1.991, 2),
64 Arguments.of(2, 2),
65 Arguments.of(2.009, 2),
66 Arguments.of(100.5, 100)
67 );
68 }
69}