diff options
author | 2023-08-08 17:52:58 +0200 | |
---|---|---|
committer | 2023-08-08 17:52:58 +0200 | |
commit | dddea012f920f922a94157c740d99a3b5a474f6e (patch) | |
tree | 3a06accc899e85ee296f5486e5b376051205d067 /subprojects/store | |
parent | Tests + small changes for AbstractNeighbourhoodCalculator and StateEquivalenc... (diff) | |
download | refinery-dddea012f920f922a94157c740d99a3b5a474f6e.tar.gz refinery-dddea012f920f922a94157c740d99a3b5a474f6e.tar.zst refinery-dddea012f920f922a94157c740d99a3b5a474f6e.zip |
Non-lazy NeighbourhoodCalculator for more accurate StateCoderBuilderImpl.
Diffstat (limited to 'subprojects/store')
7 files changed, 152 insertions, 181 deletions
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/internal/StateCoderBuilderImpl.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/internal/StateCoderBuilderImpl.java index 8268a826..05b47c52 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/internal/StateCoderBuilderImpl.java +++ b/subprojects/store/src/main/java/tools/refinery/store/statecoding/internal/StateCoderBuilderImpl.java | |||
@@ -10,11 +10,8 @@ import tools.refinery.store.model.ModelStore; | |||
10 | import tools.refinery.store.model.ModelStoreBuilder; | 10 | import tools.refinery.store.model.ModelStoreBuilder; |
11 | import tools.refinery.store.representation.AnySymbol; | 11 | import tools.refinery.store.representation.AnySymbol; |
12 | import tools.refinery.store.representation.Symbol; | 12 | import tools.refinery.store.representation.Symbol; |
13 | import tools.refinery.store.statecoding.StateCodeCalculatorFactory; | 13 | import tools.refinery.store.statecoding.*; |
14 | import tools.refinery.store.statecoding.StateCoderBuilder; | 14 | import tools.refinery.store.statecoding.neighbourhood.NeighbourhoodCalculator; |
15 | import tools.refinery.store.statecoding.StateCoderStoreAdapter; | ||
16 | import tools.refinery.store.statecoding.StateEquivalenceChecker; | ||
17 | import tools.refinery.store.statecoding.neighbourhood.LazyNeighbourhoodCalculatorFactory; | ||
18 | import tools.refinery.store.statecoding.stateequivalence.StateEquivalenceCheckerImpl; | 15 | import tools.refinery.store.statecoding.stateequivalence.StateEquivalenceCheckerImpl; |
19 | import tools.refinery.store.tuple.Tuple1; | 16 | import tools.refinery.store.tuple.Tuple1; |
20 | 17 | ||
@@ -24,7 +21,7 @@ public class StateCoderBuilderImpl implements StateCoderBuilder { | |||
24 | Set<AnySymbol> excluded = new HashSet<>(); | 21 | Set<AnySymbol> excluded = new HashSet<>(); |
25 | IntHashSet individuals = new IntHashSet(); | 22 | IntHashSet individuals = new IntHashSet(); |
26 | 23 | ||
27 | StateCodeCalculatorFactory calculator = new LazyNeighbourhoodCalculatorFactory(); | 24 | StateCodeCalculatorFactory calculator = NeighbourhoodCalculator::new; |
28 | StateEquivalenceChecker checker = new StateEquivalenceCheckerImpl(); | 25 | StateEquivalenceChecker checker = new StateEquivalenceCheckerImpl(); |
29 | 26 | ||
30 | @Override | 27 | @Override |
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 c3f8a586..8fcf24b1 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 | |||
@@ -7,7 +7,6 @@ package tools.refinery.store.statecoding.neighbourhood; | |||
7 | 7 | ||
8 | import org.eclipse.collections.api.set.primitive.IntSet; | 8 | import org.eclipse.collections.api.set.primitive.IntSet; |
9 | import org.eclipse.collections.impl.map.mutable.primitive.IntLongHashMap; | 9 | import org.eclipse.collections.impl.map.mutable.primitive.IntLongHashMap; |
10 | import org.eclipse.collections.impl.map.mutable.primitive.LongIntHashMap; | ||
11 | import tools.refinery.store.model.Interpretation; | 10 | import tools.refinery.store.model.Interpretation; |
12 | import tools.refinery.store.statecoding.ObjectCode; | 11 | import tools.refinery.store.statecoding.ObjectCode; |
13 | import tools.refinery.store.tuple.Tuple; | 12 | import tools.refinery.store.tuple.Tuple; |
@@ -20,6 +19,8 @@ public abstract class AbstractNeighbourhoodCalculator { | |||
20 | protected final LinkedHashMap<Interpretation<?>, long[]> impactValues; | 19 | protected final LinkedHashMap<Interpretation<?>, long[]> impactValues; |
21 | protected final IntLongHashMap individualHashValues; | 20 | protected final IntLongHashMap individualHashValues; |
22 | 21 | ||
22 | protected static final long PRIME = 31; | ||
23 | |||
23 | protected AbstractNeighbourhoodCalculator(List<? extends Interpretation<?>> interpretations, IntSet individuals) { | 24 | protected AbstractNeighbourhoodCalculator(List<? extends Interpretation<?>> interpretations, IntSet individuals) { |
24 | this.nullImpactValues = new ArrayList<>(); | 25 | this.nullImpactValues = new ArrayList<>(); |
25 | this.impactValues = new LinkedHashMap<>(); | 26 | this.impactValues = new LinkedHashMap<>(); |
@@ -45,25 +46,25 @@ public abstract class AbstractNeighbourhoodCalculator { | |||
45 | } | 46 | } |
46 | } | 47 | } |
47 | 48 | ||
48 | protected void initializeWithIndividuals(ObjectCodeImpl previous, LongIntHashMap hash2Amount) { | 49 | protected void initializeWithIndividuals(ObjectCodeImpl previous) { |
49 | for (var entry : individualHashValues.keyValuesView()) { | 50 | for (var entry : individualHashValues.keyValuesView()) { |
50 | previous.set(entry.getOne(), entry.getTwo()); | 51 | previous.set(entry.getOne(), entry.getTwo()); |
51 | hash2Amount.put(entry.getTwo(), 1); | ||
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
55 | protected long getTupleHash1(Tuple tuple, Object value, ObjectCode objectCodeImpl) { | 55 | protected long getTupleHash1(Tuple tuple, Object value, ObjectCode objectCodeImpl) { |
56 | long result = Objects.hashCode(value); | 56 | long result = Objects.hashCode(value); |
57 | result = result * 31 + objectCodeImpl.get(tuple.get(0)); | 57 | result = result * PRIME + objectCodeImpl.get(tuple.get(0)); |
58 | return result; | 58 | return result; |
59 | } | 59 | } |
60 | 60 | ||
61 | protected long getTupleHash2(Tuple tuple, Object value, ObjectCode objectCodeImpl) { | 61 | protected long getTupleHash2(Tuple tuple, Object value, ObjectCode objectCodeImpl) { |
62 | long result = Objects.hashCode(value); | 62 | long result = Objects.hashCode(value); |
63 | result = result * 31 + objectCodeImpl.get(tuple.get(0)); | 63 | result = result * PRIME + objectCodeImpl.get(tuple.get(0)); |
64 | result = result * 31 + objectCodeImpl.get(tuple.get(1)); | 64 | result = result * PRIME + objectCodeImpl.get(tuple.get(1)); |
65 | if (tuple.get(0) == tuple.get(1)) { | 65 | if (tuple.get(0) == tuple.get(1)) { |
66 | result *= 31; | 66 | result += PRIME; |
67 | result *= PRIME; | ||
67 | } | 68 | } |
68 | return result; | 69 | return result; |
69 | } | 70 | } |
@@ -71,7 +72,7 @@ public abstract class AbstractNeighbourhoodCalculator { | |||
71 | protected long getTupleHashN(Tuple tuple, Object value, ObjectCode objectCodeImpl) { | 72 | protected long getTupleHashN(Tuple tuple, Object value, ObjectCode objectCodeImpl) { |
72 | long result = Objects.hashCode(value); | 73 | long result = Objects.hashCode(value); |
73 | for (int i = 0; i < tuple.getSize(); i++) { | 74 | for (int i = 0; i < tuple.getSize(); i++) { |
74 | result = result * 31 + objectCodeImpl.get(tuple.get(i)); | 75 | result = result * PRIME + objectCodeImpl.get(tuple.get(i)); |
75 | } | 76 | } |
76 | return result; | 77 | return result; |
77 | } | 78 | } |
@@ -84,7 +85,7 @@ public abstract class AbstractNeighbourhoodCalculator { | |||
84 | protected long calculateModelCode(long lastSum) { | 85 | protected long calculateModelCode(long lastSum) { |
85 | long result = 0; | 86 | long result = 0; |
86 | for (var nullImpactValue : nullImpactValues) { | 87 | for (var nullImpactValue : nullImpactValues) { |
87 | result = result * 31 + Objects.hashCode(nullImpactValue.get(Tuple0.INSTANCE)); | 88 | result = result * PRIME + Objects.hashCode(nullImpactValue.get(Tuple0.INSTANCE)); |
88 | } | 89 | } |
89 | result += lastSum; | 90 | result += lastSum; |
90 | return result; | 91 | return result; |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/CollectionNeighbourhoodCalculator.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/CollectionNeighbourhoodCalculator.java deleted file mode 100644 index 058750ee..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/CollectionNeighbourhoodCalculator.java +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.statecoding.neighbourhood; | ||
7 | |||
8 | import org.eclipse.collections.api.set.primitive.MutableLongSet; | ||
9 | import org.eclipse.collections.impl.set.mutable.primitive.LongHashSet; | ||
10 | import tools.refinery.store.model.Interpretation; | ||
11 | import tools.refinery.store.statecoding.StateCodeCalculator; | ||
12 | import tools.refinery.store.statecoding.StateCoderResult; | ||
13 | import tools.refinery.store.tuple.Tuple; | ||
14 | import tools.refinery.store.tuple.Tuple0; | ||
15 | |||
16 | import java.util.ArrayList; | ||
17 | import java.util.LinkedHashMap; | ||
18 | import java.util.List; | ||
19 | import java.util.Random; | ||
20 | |||
21 | public class CollectionNeighbourhoodCalculator implements StateCodeCalculator { | ||
22 | protected final List<Interpretation<?>> nullImpactValues; | ||
23 | protected final LinkedHashMap<Interpretation<?>, long[]> impactValues; | ||
24 | |||
25 | public CollectionNeighbourhoodCalculator(List<? extends Interpretation<?>> interpretations) { | ||
26 | this.nullImpactValues = new ArrayList<>(); | ||
27 | this.impactValues = new LinkedHashMap<>(); | ||
28 | Random random = new Random(1); | ||
29 | |||
30 | for (Interpretation<?> interpretation : interpretations) { | ||
31 | int arity = interpretation.getSymbol().arity(); | ||
32 | if (arity == 0) { | ||
33 | nullImpactValues.add(interpretation); | ||
34 | } else { | ||
35 | long[] impact = new long[arity]; | ||
36 | for (int i = 0; i < arity; i++) { | ||
37 | impact[i] = random.nextLong(); | ||
38 | } | ||
39 | impactValues.put(interpretation, impact); | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | |||
44 | @Override | ||
45 | public StateCoderResult calculateCodes() { | ||
46 | ObjectCodeImpl previous = new ObjectCodeImpl(); | ||
47 | ObjectCodeImpl next = new ObjectCodeImpl(); | ||
48 | |||
49 | int previousSize = 1; | ||
50 | long lastSum; | ||
51 | boolean grows; | ||
52 | |||
53 | do{ | ||
54 | for (var impactValueEntry : this.impactValues.entrySet()) { | ||
55 | Interpretation<?> interpretation = impactValueEntry.getKey(); | ||
56 | long[] impact = impactValueEntry.getValue(); | ||
57 | var cursor = interpretation.getAll(); | ||
58 | while (cursor.move()) { | ||
59 | Tuple tuple = cursor.getKey(); | ||
60 | Object value = cursor.getValue(); | ||
61 | long tupleHash = getTupleHash(tuple, value, previous); | ||
62 | addHash(next, tuple, impact, tupleHash); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | previous = next; | ||
67 | next = null; | ||
68 | lastSum = 0; | ||
69 | MutableLongSet codes = new LongHashSet(); | ||
70 | for (int i = 0; i < previous.getSize(); i++) { | ||
71 | long objectHash = previous.get(i); | ||
72 | codes.add(objectHash); | ||
73 | |||
74 | final long shifted1 = objectHash>>> 32; | ||
75 | final long shifted2 = objectHash << 32; | ||
76 | lastSum += shifted1 + shifted2; | ||
77 | } | ||
78 | int nextSize = codes.size(); | ||
79 | grows = previousSize < nextSize; | ||
80 | previousSize = nextSize; | ||
81 | |||
82 | if(grows) { | ||
83 | next = new ObjectCodeImpl(previous); | ||
84 | } | ||
85 | } while (grows); | ||
86 | |||
87 | long result = 1; | ||
88 | for (var nullImpactValue : nullImpactValues) { | ||
89 | result = result * 31 + nullImpactValue.get(Tuple0.INSTANCE).hashCode(); | ||
90 | } | ||
91 | result += lastSum; | ||
92 | |||
93 | return new StateCoderResult((int) result, previous); | ||
94 | } | ||
95 | |||
96 | protected long getTupleHash(Tuple tuple, Object value, ObjectCodeImpl objectCodeImpl) { | ||
97 | long result = value.hashCode(); | ||
98 | int arity = tuple.getSize(); | ||
99 | if (arity == 1) { | ||
100 | result = result * 31 + objectCodeImpl.get(tuple.get(0)); | ||
101 | } else if (arity == 2) { | ||
102 | result = result * 31 + objectCodeImpl.get(tuple.get(0)); | ||
103 | result = result * 31 + objectCodeImpl.get(tuple.get(1)); | ||
104 | if (tuple.get(0) == tuple.get(1)) { | ||
105 | result++; | ||
106 | } | ||
107 | } else if (arity > 2) { | ||
108 | for (int i = 0; i < arity; i++) { | ||
109 | result = result * 31 + objectCodeImpl.get(tuple.get(i)); | ||
110 | } | ||
111 | } | ||
112 | return result; | ||
113 | } | ||
114 | |||
115 | protected void addHash(ObjectCodeImpl objectCodeImpl, Tuple tuple, long[] impact, long tupleHashCode) { | ||
116 | if (tuple.getSize() == 1) { | ||
117 | addHash(objectCodeImpl, tuple.get(0), impact[0], tupleHashCode); | ||
118 | } else if (tuple.getSize() == 2) { | ||
119 | addHash(objectCodeImpl, tuple.get(0), impact[0], tupleHashCode); | ||
120 | addHash(objectCodeImpl, tuple.get(1), impact[1], tupleHashCode); | ||
121 | } else if (tuple.getSize() > 2) { | ||
122 | for (int i = 0; i < tuple.getSize(); i++) { | ||
123 | addHash(objectCodeImpl, tuple.get(i), impact[i], tupleHashCode); | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | |||
128 | protected void addHash(ObjectCodeImpl objectCodeImpl, int o, long impact, long tupleHash) { | ||
129 | objectCodeImpl.set(o, objectCodeImpl.get(o) + tupleHash * impact); | ||
130 | } | ||
131 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/LazyNeighbourhoodCalculator.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/LazyNeighbourhoodCalculator.java index 98a75e08..2ffbef5e 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/LazyNeighbourhoodCalculator.java +++ b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/LazyNeighbourhoodCalculator.java | |||
@@ -22,34 +22,41 @@ public class LazyNeighbourhoodCalculator extends AbstractNeighbourhoodCalculator | |||
22 | } | 22 | } |
23 | 23 | ||
24 | public StateCoderResult calculateCodes() { | 24 | public StateCoderResult calculateCodes() { |
25 | ObjectCodeImpl previous = new ObjectCodeImpl(); | 25 | ObjectCodeImpl previousObjectCode = new ObjectCodeImpl(); |
26 | LongIntHashMap hash2Amount = new LongIntHashMap(); | 26 | LongIntHashMap prevHash2Amount = new LongIntHashMap(); |
27 | |||
28 | initializeWithIndividuals(previous, hash2Amount); | ||
29 | 27 | ||
30 | long lastSum; | 28 | long lastSum; |
31 | // All hash code is 0, except to the individuals. | 29 | // All hash code is 0, except to the individuals. |
32 | int lastSize = hash2Amount.size() + 1; | 30 | int lastSize = 1; |
31 | boolean first = true; | ||
33 | 32 | ||
34 | boolean grows; | 33 | boolean grows; |
34 | int rounds = 0; | ||
35 | do { | 35 | do { |
36 | ObjectCodeImpl next = new ObjectCodeImpl(); | 36 | final ObjectCodeImpl nextObjectCode; |
37 | constructNextObjectCodes(previous, next, hash2Amount); | 37 | if (first) { |
38 | nextObjectCode = new ObjectCodeImpl(); | ||
39 | initializeWithIndividuals(nextObjectCode); | ||
40 | } else { | ||
41 | nextObjectCode = new ObjectCodeImpl(previousObjectCode); | ||
42 | } | ||
43 | constructNextObjectCodes(previousObjectCode, nextObjectCode, prevHash2Amount); | ||
38 | 44 | ||
39 | LongIntHashMap nextHash2Amount = new LongIntHashMap(); | 45 | LongIntHashMap nextHash2Amount = new LongIntHashMap(); |
40 | lastSum = calculateLastSum(previous, next, hash2Amount, nextHash2Amount); | 46 | lastSum = calculateLastSum(previousObjectCode, nextObjectCode, prevHash2Amount, nextHash2Amount); |
41 | 47 | ||
42 | int nextSize = nextHash2Amount.size(); | 48 | int nextSize = nextHash2Amount.size(); |
43 | grows = nextSize > lastSize; | 49 | grows = nextSize > lastSize; |
44 | lastSize = nextSize; | 50 | lastSize = nextSize; |
51 | first = false; | ||
45 | 52 | ||
46 | previous = next; | 53 | previousObjectCode = nextObjectCode; |
47 | hash2Amount = nextHash2Amount; | 54 | prevHash2Amount = nextHash2Amount; |
48 | } while (grows); | 55 | } while (grows && rounds++ < 4/*&& lastSize < previousObjectCode.getSize()*/); |
49 | 56 | ||
50 | long result = calculateModelCode(lastSum); | 57 | long result = calculateModelCode(lastSum); |
51 | 58 | ||
52 | return new StateCoderResult((int) result, previous); | 59 | return new StateCoderResult((int) result, previousObjectCode); |
53 | } | 60 | } |
54 | 61 | ||
55 | private long calculateLastSum(ObjectCodeImpl previous, ObjectCodeImpl next, LongIntMap hash2Amount, | 62 | private long calculateLastSum(ObjectCodeImpl previous, ObjectCodeImpl next, LongIntMap hash2Amount, |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/LazyNeighbourhoodCalculatorFactory.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/LazyNeighbourhoodCalculatorFactory.java deleted file mode 100644 index 2e499f95..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/LazyNeighbourhoodCalculatorFactory.java +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.statecoding.neighbourhood; | ||
7 | |||
8 | import org.eclipse.collections.api.set.primitive.IntSet; | ||
9 | import tools.refinery.store.model.Interpretation; | ||
10 | import tools.refinery.store.statecoding.StateCodeCalculator; | ||
11 | import tools.refinery.store.statecoding.StateCodeCalculatorFactory; | ||
12 | |||
13 | import java.util.List; | ||
14 | |||
15 | public class LazyNeighbourhoodCalculatorFactory implements StateCodeCalculatorFactory { | ||
16 | @Override | ||
17 | public StateCodeCalculator create(List<? extends Interpretation<?>> interpretations, IntSet individuals) { | ||
18 | return new LazyNeighbourhoodCalculator(interpretations,individuals); | ||
19 | } | ||
20 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/NeighbourhoodCalculator.java b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/NeighbourhoodCalculator.java new file mode 100644 index 00000000..d3b3ccae --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/statecoding/neighbourhood/NeighbourhoodCalculator.java | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.statecoding.neighbourhood; | ||
7 | |||
8 | import org.eclipse.collections.api.set.primitive.IntSet; | ||
9 | import tools.refinery.store.map.Cursor; | ||
10 | import tools.refinery.store.model.Interpretation; | ||
11 | import tools.refinery.store.statecoding.ObjectCode; | ||
12 | import tools.refinery.store.statecoding.StateCodeCalculator; | ||
13 | import tools.refinery.store.statecoding.StateCoderResult; | ||
14 | import tools.refinery.store.tuple.Tuple; | ||
15 | import tools.refinery.store.tuple.Tuple0; | ||
16 | |||
17 | import java.util.List; | ||
18 | import java.util.Objects; | ||
19 | |||
20 | public class NeighbourhoodCalculator extends AbstractNeighbourhoodCalculator implements StateCodeCalculator { | ||
21 | public NeighbourhoodCalculator(List<? extends Interpretation<?>> interpretations, IntSet individuals) { | ||
22 | super(interpretations, individuals); | ||
23 | } | ||
24 | |||
25 | public StateCoderResult calculateCodes() { | ||
26 | ObjectCodeImpl previousObjectCode = new ObjectCodeImpl(); | ||
27 | initializeWithIndividuals(previousObjectCode); | ||
28 | |||
29 | int rounds = 0; | ||
30 | do { | ||
31 | final ObjectCodeImpl nextObjectCode = rounds == 0 ? new ObjectCodeImpl() : | ||
32 | new ObjectCodeImpl(previousObjectCode.getSize()); | ||
33 | |||
34 | constructNextObjectCodes(previousObjectCode, nextObjectCode); | ||
35 | previousObjectCode = nextObjectCode; | ||
36 | rounds++; | ||
37 | } while (rounds <= 7 && rounds <= previousObjectCode.getSize()); | ||
38 | |||
39 | long result = calculateLastSum(previousObjectCode); | ||
40 | return new StateCoderResult((int) result, previousObjectCode); | ||
41 | } | ||
42 | |||
43 | private long calculateLastSum(ObjectCode codes) { | ||
44 | long result = 0; | ||
45 | for (var nullImpactValue : nullImpactValues) { | ||
46 | result = result * 31 + Objects.hashCode(nullImpactValue.get(Tuple0.INSTANCE)); | ||
47 | } | ||
48 | |||
49 | for (int i = 0; i < codes.getSize(); i++) { | ||
50 | final long hash = codes.get(i); | ||
51 | result += hash*PRIME; | ||
52 | } | ||
53 | |||
54 | return result; | ||
55 | } | ||
56 | |||
57 | private void constructNextObjectCodes(ObjectCodeImpl previous, ObjectCodeImpl next) { | ||
58 | for (var impactValueEntry : this.impactValues.entrySet()) { | ||
59 | Interpretation<?> interpretation = impactValueEntry.getKey(); | ||
60 | var cursor = interpretation.getAll(); | ||
61 | int arity = interpretation.getSymbol().arity(); | ||
62 | long[] impactValue = impactValueEntry.getValue(); | ||
63 | |||
64 | if (arity == 1) { | ||
65 | while (cursor.move()) { | ||
66 | impactCalculation1(previous, next, impactValue, cursor); | ||
67 | } | ||
68 | } else if (arity == 2) { | ||
69 | while (cursor.move()) { | ||
70 | impactCalculation2(previous, next, impactValue, cursor); | ||
71 | } | ||
72 | } else { | ||
73 | while (cursor.move()) { | ||
74 | impactCalculationN(previous, next, impactValue, cursor); | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | |||
81 | private void impactCalculation1(ObjectCodeImpl previous, ObjectCodeImpl next, long[] impactValues, Cursor<Tuple, ?> cursor) { | ||
82 | |||
83 | Tuple tuple = cursor.getKey(); | ||
84 | int o = tuple.get(0); | ||
85 | Object value = cursor.getValue(); | ||
86 | long tupleHash = getTupleHash1(tuple, value, previous); | ||
87 | addHash(next, o, impactValues[0], tupleHash); | ||
88 | } | ||
89 | |||
90 | private void impactCalculation2(ObjectCodeImpl previous, ObjectCodeImpl next, long[] impactValues, Cursor<Tuple, ?> cursor) { | ||
91 | final Tuple tuple = cursor.getKey(); | ||
92 | final int o1 = tuple.get(0); | ||
93 | final int o2 = tuple.get(1); | ||
94 | |||
95 | Object value = cursor.getValue(); | ||
96 | long tupleHash = getTupleHash2(tuple, value, previous); | ||
97 | |||
98 | addHash(next, o1, impactValues[0], tupleHash); | ||
99 | addHash(next, o2, impactValues[1], tupleHash); | ||
100 | } | ||
101 | |||
102 | private void impactCalculationN(ObjectCodeImpl previous, ObjectCodeImpl next, long[] impactValues, Cursor<Tuple, ?> cursor) { | ||
103 | final Tuple tuple = cursor.getKey(); | ||
104 | |||
105 | Object value = cursor.getValue(); | ||
106 | long tupleHash = getTupleHashN(tuple, value, previous); | ||
107 | |||
108 | for (int i = 0; i < tuple.getSize(); i++) { | ||
109 | addHash(next, tuple.get(i), impactValues[i], tupleHash); | ||
110 | } | ||
111 | } | ||
112 | } | ||
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 c4d86cf1..0d629176 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 | |||
@@ -18,9 +18,14 @@ public class ObjectCodeImpl implements ObjectCode { | |||
18 | size = 0; | 18 | size = 0; |
19 | } | 19 | } |
20 | 20 | ||
21 | public ObjectCodeImpl(ObjectCodeImpl sameSize) { | 21 | public ObjectCodeImpl(int size) { |
22 | this.vector = new long[sameSize.size]; | 22 | this.vector = new long[size]; |
23 | this.size = sameSize.size; | 23 | this.size = size; |
24 | } | ||
25 | |||
26 | public ObjectCodeImpl(ObjectCodeImpl copy) { | ||
27 | this.vector = Arrays.copyOf(copy.vector,copy.size); | ||
28 | this.size = copy.size; | ||
24 | } | 29 | } |
25 | 30 | ||
26 | public void ensureSize(int object) { | 31 | public void ensureSize(int object) { |