aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects
diff options
context:
space:
mode:
authorLibravatar OszkarSemerath <semerath@mit.bme.hu>2023-08-07 16:07:09 +0200
committerLibravatar OszkarSemerath <semerath@mit.bme.hu>2023-08-07 16:07:09 +0200
commit36550e2be2146b290210cb12c76d0341e499f849 (patch)
treebe37f1544c1ee655d95e0139d881990dd014dc7f /subprojects
parentStateCoderBuilder improvement with individuals, and customizable calculators. (diff)
downloadrefinery-36550e2be2146b290210cb12c76d0341e499f849.tar.gz
refinery-36550e2be2146b290210cb12c76d0341e499f849.tar.zst
refinery-36550e2be2146b290210cb12c76d0341e499f849.zip
Tests + small changes for AbstractNeighbourhoodCalculator and StateEquivalenceCheckerImpl
Diffstat (limited to 'subprojects')
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/AbstractNeighbourhoodCalculator.java15
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/ObjectCodeImpl.java3
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/statecoding/stateequivalence/StateEquivalenceCheckerImpl.java19
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/statecoding/EquivalenceTest.java178
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/statecoding/StateCoderUnitTest.java195
5 files changed, 390 insertions, 20 deletions
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/AbstractNeighbourhoodCalculator.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/AbstractNeighbourhoodCalculator.java
index 0de76519..c3f8a586 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/AbstractNeighbourhoodCalculator.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/AbstractNeighbourhoodCalculator.java
@@ -13,10 +13,7 @@ import tools.refinery.store.statecoding.ObjectCode;
13import tools.refinery.store.tuple.Tuple; 13import tools.refinery.store.tuple.Tuple;
14import tools.refinery.store.tuple.Tuple0; 14import tools.refinery.store.tuple.Tuple0;
15 15
16import java.util.ArrayList; 16import java.util.*;
17import java.util.LinkedHashMap;
18import java.util.List;
19import java.util.Random;
20 17
21public abstract class AbstractNeighbourhoodCalculator { 18public abstract class AbstractNeighbourhoodCalculator {
22 protected final List<Interpretation<?>> nullImpactValues; 19 protected final List<Interpretation<?>> nullImpactValues;
@@ -56,13 +53,13 @@ public abstract class AbstractNeighbourhoodCalculator {
56 } 53 }
57 54
58 protected long getTupleHash1(Tuple tuple, Object value, ObjectCode objectCodeImpl) { 55 protected long getTupleHash1(Tuple tuple, Object value, ObjectCode objectCodeImpl) {
59 long result = value.hashCode(); 56 long result = Objects.hashCode(value);
60 result = result * 31 + objectCodeImpl.get(tuple.get(0)); 57 result = result * 31 + objectCodeImpl.get(tuple.get(0));
61 return result; 58 return result;
62 } 59 }
63 60
64 protected long getTupleHash2(Tuple tuple, Object value, ObjectCode objectCodeImpl) { 61 protected long getTupleHash2(Tuple tuple, Object value, ObjectCode objectCodeImpl) {
65 long result = value.hashCode(); 62 long result = Objects.hashCode(value);
66 result = result * 31 + objectCodeImpl.get(tuple.get(0)); 63 result = result * 31 + objectCodeImpl.get(tuple.get(0));
67 result = result * 31 + objectCodeImpl.get(tuple.get(1)); 64 result = result * 31 + objectCodeImpl.get(tuple.get(1));
68 if (tuple.get(0) == tuple.get(1)) { 65 if (tuple.get(0) == tuple.get(1)) {
@@ -72,7 +69,7 @@ public abstract class AbstractNeighbourhoodCalculator {
72 } 69 }
73 70
74 protected long getTupleHashN(Tuple tuple, Object value, ObjectCode objectCodeImpl) { 71 protected long getTupleHashN(Tuple tuple, Object value, ObjectCode objectCodeImpl) {
75 long result = value.hashCode(); 72 long result = Objects.hashCode(value);
76 for (int i = 0; i < tuple.getSize(); i++) { 73 for (int i = 0; i < tuple.getSize(); i++) {
77 result = result * 31 + objectCodeImpl.get(tuple.get(i)); 74 result = result * 31 + objectCodeImpl.get(tuple.get(i));
78 } 75 }
@@ -85,9 +82,9 @@ public abstract class AbstractNeighbourhoodCalculator {
85 } 82 }
86 83
87 protected long calculateModelCode(long lastSum) { 84 protected long calculateModelCode(long lastSum) {
88 long result = 1; 85 long result = 0;
89 for (var nullImpactValue : nullImpactValues) { 86 for (var nullImpactValue : nullImpactValues) {
90 result = result * 31 + nullImpactValue.get(Tuple0.INSTANCE).hashCode(); 87 result = result * 31 + Objects.hashCode(nullImpactValue.get(Tuple0.INSTANCE));
91 } 88 }
92 result += lastSum; 89 result += lastSum;
93 return result; 90 return result;
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/ObjectCodeImpl.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/ObjectCodeImpl.java
index 08e3a90b..c4d86cf1 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/ObjectCodeImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/ObjectCodeImpl.java
@@ -50,7 +50,8 @@ public class ObjectCodeImpl implements ObjectCode {
50 50
51 public void set(int object, long value) { 51 public void set(int object, long value) {
52 ensureSize(object); 52 ensureSize(object);
53 vector[object]=value; 53 final long valueToPut = value == 0 ? 1 : value;
54 vector[object]=valueToPut;
54 } 55 }
55 56
56 public int getSize() { 57 public int getSize() {
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/stateequivalence/StateEquivalenceCheckerImpl.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/stateequivalence/StateEquivalenceCheckerImpl.java
index e58a2502..34dba34e 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/stateequivalence/StateEquivalenceCheckerImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/statecoding/stateequivalence/StateEquivalenceCheckerImpl.java
@@ -29,11 +29,8 @@ public class StateEquivalenceCheckerImpl implements StateEquivalenceChecker {
29 List<? extends Interpretation<?>> interpretations1, 29 List<? extends Interpretation<?>> interpretations1,
30 ObjectCode code1, 30 ObjectCode code1,
31 List<? extends Interpretation<?>> interpretations2, 31 List<? extends Interpretation<?>> interpretations2,
32 ObjectCode code2) { 32 ObjectCode code2)
33 if (code1.getSize() != code2.getSize()) { 33 {
34 return EquivalenceResult.DIFFERENT;
35 }
36
37 IntIntHashMap object2PermutationGroup = new IntIntHashMap(); 34 IntIntHashMap object2PermutationGroup = new IntIntHashMap();
38 List<List<IntIntMap>> permutationsGroups = new ArrayList<>(); 35 List<List<IntIntMap>> permutationsGroups = new ArrayList<>();
39 36
@@ -69,12 +66,14 @@ public class StateEquivalenceCheckerImpl implements StateEquivalenceChecker {
69 for (int o = 0; o < code.getSize(); o++) { 66 for (int o = 0; o < code.getSize(); o++) {
70 if(! individuals.contains(o)){ 67 if(! individuals.contains(o)){
71 long hash = code.get(o); 68 long hash = code.get(o);
72 var equivalenceClass = result.get(hash); 69 if(hash != 0) {
73 if (equivalenceClass == null) { 70 var equivalenceClass = result.get(hash);
74 equivalenceClass = new IntHashSet(); 71 if (equivalenceClass == null) {
75 result.put(hash, equivalenceClass); 72 equivalenceClass = new IntHashSet();
73 result.put(hash, equivalenceClass);
74 }
75 equivalenceClass.add(o);
76 } 76 }
77 equivalenceClass.add(o);
78 } 77 }
79 } 78 }
80 return result; 79 return result;
diff --git a/subprojects/store/src/test/java/tools/refinery/store/statecoding/EquivalenceTest.java b/subprojects/store/src/test/java/tools/refinery/store/statecoding/EquivalenceTest.java
new file mode 100644
index 00000000..8a9c0e9b
--- /dev/null
+++ b/subprojects/store/src/test/java/tools/refinery/store/statecoding/EquivalenceTest.java
@@ -0,0 +1,178 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.statecoding;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.map.Version;
10import tools.refinery.store.model.Model;
11import tools.refinery.store.model.ModelStore;
12import tools.refinery.store.representation.Symbol;
13import tools.refinery.store.tuple.Tuple;
14
15import static org.junit.jupiter.api.Assertions.assertEquals;
16
17class EquivalenceTest {
18 Symbol<Boolean> person = new Symbol<>("Person", 1, Boolean.class, false);
19 Symbol<Integer> age = new Symbol<>("age", 1, Integer.class, null);
20 Symbol<Boolean> friend = new Symbol<>("friend", 2, Boolean.class, false);
21 Symbol<Boolean> parents = new Symbol<>("parents", 3, Boolean.class, false);
22 Symbol<Integer> population = new Symbol<>("population", 0, Integer.class, 0);
23
24 private ModelStore createStore() {
25 return ModelStore.builder()
26 .symbols(person, age, friend, parents, population)
27 .with(StateCoderAdapter.builder())
28 .build();
29 }
30
31 @Test
32 void emptyModelCode0() {
33 ModelStore store = createStore();
34 var stateCoder = store.getAdapter(StateCoderStoreAdapter.class);
35 Model model = createStore().createEmptyModel();
36 Version v1 = model.commit();
37 Version v2 = model.commit();
38
39 assertEquals(StateEquivalenceChecker.EquivalenceResult.ISOMORPHIC, stateCoder.checkEquivalence(v1, v2));
40
41 var personI = model.getInterpretation(person);
42 var friendI = model.getInterpretation(friend);
43
44 personI.put(Tuple.of(1), true);
45 personI.put(Tuple.of(2), true);
46 friendI.put(Tuple.of(1, 2), true);
47
48 Version v3 = model.commit();
49
50 assertEquals(StateEquivalenceChecker.EquivalenceResult.DIFFERENT, stateCoder.checkEquivalence(v1, v3));
51 }
52
53 @Test
54 void nullRelationTest() {
55 ModelStore store = createStore();
56 var stateCoder = store.getAdapter(StateCoderStoreAdapter.class);
57 Model model = createStore().createEmptyModel();
58
59 var populationI = model.getInterpretation(population);
60
61 Version v1 = model.commit();
62
63 populationI.put(Tuple.of(), 1);
64 Version v2 = model.commit();
65
66 assertEquals(StateEquivalenceChecker.EquivalenceResult.DIFFERENT, stateCoder.checkEquivalence(v1, v2));
67
68 populationI.put(Tuple.of(), 2);
69 Version v3 = model.commit();
70
71 assertEquals(StateEquivalenceChecker.EquivalenceResult.DIFFERENT, stateCoder.checkEquivalence(v2, v3));
72 }
73
74 @Test
75 void unaryBooleanTest() {
76 ModelStore store = createStore();
77 var stateCoder = store.getAdapter(StateCoderStoreAdapter.class);
78 Model model = createStore().createEmptyModel();
79
80 var personI = model.getInterpretation(person);
81
82 Version v1 = model.commit();
83
84 personI.put(Tuple.of(1), true);
85 Version v2 = model.commit();
86
87 assertEquals(StateEquivalenceChecker.EquivalenceResult.DIFFERENT, stateCoder.checkEquivalence(v1, v2));
88
89 personI.put(Tuple.of(2), true);
90 Version v3 = model.commit();
91
92 assertEquals(StateEquivalenceChecker.EquivalenceResult.DIFFERENT, stateCoder.checkEquivalence(v2, v3));
93
94 personI.put(Tuple.of(1), false);
95 Version v4 = model.commit();
96
97 assertEquals(StateEquivalenceChecker.EquivalenceResult.ISOMORPHIC, stateCoder.checkEquivalence(v2, v4));
98 }
99
100 @Test
101 void unaryIntTest() {
102 ModelStore store = createStore();
103 var stateCoder = store.getAdapter(StateCoderStoreAdapter.class);
104 Model model = createStore().createEmptyModel();
105
106 var ageI = model.getInterpretation(age);
107
108 ageI.put(Tuple.of(1), 3);
109 Version v1 = model.commit();
110
111 ageI.put(Tuple.of(1), 4);
112 Version v2 = model.commit();
113
114 assertEquals(StateEquivalenceChecker.EquivalenceResult.DIFFERENT, stateCoder.checkEquivalence(v1, v2));
115
116 ageI.put(Tuple.of(2), 4);
117 Version v3 = model.commit();
118
119 assertEquals(StateEquivalenceChecker.EquivalenceResult.DIFFERENT, stateCoder.checkEquivalence(v2, v3));
120
121 ageI.put(Tuple.of(1), null);
122 Version v4 = model.commit();
123
124 assertEquals(StateEquivalenceChecker.EquivalenceResult.ISOMORPHIC, stateCoder.checkEquivalence(v2, v4));
125 }
126
127 @Test
128 void binaryTest() {
129 ModelStore store = createStore();
130 var stateCoder = store.getAdapter(StateCoderStoreAdapter.class);
131 Model model = createStore().createEmptyModel();
132
133 var friendI = model.getInterpretation(friend);
134
135 Version v1 = model.commit();
136
137 friendI.put(Tuple.of(1, 2), true);
138 Version v2 = model.commit();
139
140 assertEquals(StateEquivalenceChecker.EquivalenceResult.DIFFERENT, stateCoder.checkEquivalence(v1, v2));
141
142 friendI.put(Tuple.of(2, 1), true);
143 Version v3 = model.commit();
144
145 assertEquals(StateEquivalenceChecker.EquivalenceResult.DIFFERENT, stateCoder.checkEquivalence(v2, v3));
146
147 friendI.put(Tuple.of(1, 2), false);
148 Version v4 = model.commit();
149
150 assertEquals(StateEquivalenceChecker.EquivalenceResult.ISOMORPHIC, stateCoder.checkEquivalence(v2, v4));
151 }
152
153 @Test
154 void NaryTest() {
155 ModelStore store = createStore();
156 var stateCoder = store.getAdapter(StateCoderStoreAdapter.class);
157 Model model = createStore().createEmptyModel();
158
159 var parentsI = model.getInterpretation(parents);
160
161 Version v1 = model.commit();
162
163 parentsI.put(Tuple.of(3, 1, 2), true);
164 Version v2 = model.commit();
165
166 assertEquals(StateEquivalenceChecker.EquivalenceResult.DIFFERENT, stateCoder.checkEquivalence(v1, v2));
167
168 parentsI.put(Tuple.of(4, 1, 2), true);
169 Version v3 = model.commit();
170
171 assertEquals(StateEquivalenceChecker.EquivalenceResult.DIFFERENT, stateCoder.checkEquivalence(v2, v3));
172
173 parentsI.put(Tuple.of(3, 1, 2), false);
174 Version v4 = model.commit();
175
176 assertEquals(StateEquivalenceChecker.EquivalenceResult.ISOMORPHIC, stateCoder.checkEquivalence(v2, v4));
177 }
178}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/statecoding/StateCoderUnitTest.java b/subprojects/store/src/test/java/tools/refinery/store/statecoding/StateCoderUnitTest.java
new file mode 100644
index 00000000..d94df841
--- /dev/null
+++ b/subprojects/store/src/test/java/tools/refinery/store/statecoding/StateCoderUnitTest.java
@@ -0,0 +1,195 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.statecoding;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.model.Model;
10import tools.refinery.store.model.ModelStore;
11import tools.refinery.store.representation.Symbol;
12import tools.refinery.store.tuple.Tuple;
13
14import java.util.Objects;
15
16import static org.junit.jupiter.api.Assertions.*;
17
18class StateCoderUnitTest {
19 Symbol<Boolean> person = new Symbol<>("Person", 1, Boolean.class, false);
20 Symbol<Integer> age = new Symbol<>("age", 1, Integer.class, null);
21 Symbol<Boolean> friend = new Symbol<>("friend", 2, Boolean.class, false);
22 Symbol<Boolean> parents = new Symbol<>("parents", 3, Boolean.class, false);
23 Symbol<Integer> population = new Symbol<>("population", 0, Integer.class, 0);
24
25 private Model createEmptyModel() {
26 var store = ModelStore.builder()
27 .symbols(person, age, friend, parents, population)
28 .with(StateCoderAdapter.builder())
29 .build();
30
31 return store.createEmptyModel();
32 }
33
34 @Test
35 void emptyModelCode0() {
36 Model model = createEmptyModel();
37 var stateCoder = model.getAdapter(StateCoderAdapter.class);
38
39 assertEquals(0, stateCoder.calculateModelCode());
40
41 var personI = model.getInterpretation(person);
42 var friendI = model.getInterpretation(friend);
43
44 personI.put(Tuple.of(1), true);
45 personI.put(Tuple.of(2), true);
46 friendI.put(Tuple.of(1, 2), true);
47
48 assertNotEquals(0, stateCoder.calculateModelCode());
49 }
50
51 @Test
52 void emptyObjectCode0() {
53 Model model = createEmptyModel();
54 var stateCoder = model.getAdapter(StateCoderAdapter.class);
55
56 var personI = model.getInterpretation(person);
57 var friendI = model.getInterpretation(friend);
58
59 assertEquals(0, stateCoder.calculateObjectCode().get(1));
60 assertEquals(0, stateCoder.calculateObjectCode().get(17));
61
62 personI.put(Tuple.of(1), true);
63 personI.put(Tuple.of(2), true);
64 friendI.put(Tuple.of(1, 2), true);
65
66 assertNotEquals(0, stateCoder.calculateObjectCode().get(1));
67 assertEquals(0, stateCoder.calculateObjectCode().get(17));
68 }
69
70 @Test
71 void nullRelationTest() {
72 Model model = createEmptyModel();
73 var stateCoder = model.getAdapter(StateCoderAdapter.class);
74
75 var populationI = model.getInterpretation(population);
76
77 final int hashOf0 = Objects.hashCode(0);
78
79 assertEquals(hashOf0, stateCoder.calculateModelCode());
80
81 populationI.put(Tuple.of(), 1);
82 int code1 = stateCoder.calculateModelCode();
83
84 assertNotEquals(hashOf0, stateCoder.calculateModelCode());
85
86 populationI.put(Tuple.of(), 2);
87 int code2 = stateCoder.calculateModelCode();
88
89 assertNotEquals(code1, code2);
90
91 populationI.put(Tuple.of(), 1);
92 assertEquals(code1, stateCoder.calculateModelCode());
93 }
94
95 @Test
96 void unaryBooleanTest() {
97 Model model = createEmptyModel();
98 var stateCoder = model.getAdapter(StateCoderAdapter.class);
99
100 var personI = model.getInterpretation(person);
101
102 assertEquals(0, stateCoder.calculateModelCode());
103
104 personI.put(Tuple.of(1), true);
105 int code1 = stateCoder.calculateModelCode();
106
107 assertNotEquals(0, stateCoder.calculateModelCode());
108
109 personI.put(Tuple.of(2), true);
110 int code2 = stateCoder.calculateModelCode();
111
112 assertNotEquals(code1, code2);
113
114 personI.put(Tuple.of(1), false);
115 assertEquals(code1, stateCoder.calculateModelCode());
116 }
117
118 @Test
119 void unaryIntTest() {
120 Model model = createEmptyModel();
121 var stateCoder = model.getAdapter(StateCoderAdapter.class);
122
123 var ageI = model.getInterpretation(age);
124
125 assertEquals(0, stateCoder.calculateModelCode());
126
127 ageI.put(Tuple.of(1), 4);
128 int code0 = stateCoder.calculateModelCode();
129
130 assertNotEquals(0, code0);
131
132 ageI.put(Tuple.of(1), 5);
133 int code1 = stateCoder.calculateModelCode();
134
135 assertNotEquals(code0, code1);
136
137 ageI.put(Tuple.of(2), 5);
138 int code2 = stateCoder.calculateModelCode();
139
140 assertNotEquals(code1, code2);
141
142 ageI.put(Tuple.of(1), null);
143 assertEquals(code1, stateCoder.calculateModelCode());
144 }
145
146 @Test
147 void binaryTest() {
148 Model model = createEmptyModel();
149 var stateCoder = model.getAdapter(StateCoderAdapter.class);
150
151 var friendI = model.getInterpretation(friend);
152
153 assertEquals(0, stateCoder.calculateModelCode());
154
155 friendI.put(Tuple.of(1, 2), true);
156 int code1 = stateCoder.calculateModelCode();
157
158 assertNotEquals(0, code1);
159
160 friendI.put(Tuple.of(2, 1), true);
161 int code2 = stateCoder.calculateModelCode();
162
163 assertNotEquals(code1, code2);
164
165 friendI.put(Tuple.of(1, 2), false);
166 int code3 = stateCoder.calculateModelCode();
167
168 assertEquals(code1, code3);
169 }
170
171 @Test
172 void NaryTest() {
173 Model model = createEmptyModel();
174 var stateCoder = model.getAdapter(StateCoderAdapter.class);
175
176 var parentsI = model.getInterpretation(parents);
177
178 assertEquals(0, stateCoder.calculateModelCode());
179
180 parentsI.put(Tuple.of(3, 1, 2), true);
181 int code1 = stateCoder.calculateModelCode();
182
183 assertNotEquals(0, code1);
184
185 parentsI.put(Tuple.of(4, 1, 2), true);
186 int code2 = stateCoder.calculateModelCode();
187
188 assertNotEquals(code1, code2);
189
190 parentsI.put(Tuple.of(3, 1, 2), false);
191 int code3 = stateCoder.calculateModelCode();
192
193 assertEquals(code1, code3);
194 }
195}