summaryrefslogtreecommitdiffstats
path: root/subprojects/language-semantics/src/main
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-09-29 17:54:03 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-10-03 20:06:52 +0200
commit7218308c9be553c3e0d2af0dabde853d0dab27cd (patch)
tree44ba305c993689235c6599aa0d40d4d883e6f687 /subprojects/language-semantics/src/main
parentfix: make Tuple1 cache thread safe (diff)
downloadrefinery-7218308c9be553c3e0d2af0dabde853d0dab27cd.tar.gz
refinery-7218308c9be553c3e0d2af0dabde853d0dab27cd.tar.zst
refinery-7218308c9be553c3e0d2af0dabde853d0dab27cd.zip
feat: data structure for default assertions
Diffstat (limited to 'subprojects/language-semantics/src/main')
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java26
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java18
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java8
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java44
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java50
5 files changed, 116 insertions, 30 deletions
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java
index d743ee2b..3893f396 100644
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java
+++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java
@@ -20,21 +20,41 @@ public class DecisionTree {
20 root = node; 20 root = node;
21 } 21 }
22 22
23 public DecisionTree(int levels) {
24 this(levels, null);
25 }
26
23 public TruthValue get(Tuple tuple) { 27 public TruthValue get(Tuple tuple) {
24 return root.getValue(levels - 1, tuple).getTruthValue(); 28 return root.getValue(levels - 1, tuple).getTruthValue();
25 } 29 }
26 30
27 public void mergeValue(Tuple tuple, TruthValue truthValue) { 31 public void mergeValue(Tuple tuple, TruthValue truthValue) {
28 if (truthValue == null) { 32 if (truthValue != null) {
29 return; 33 root.mergeValue(levels - 1, tuple, truthValue);
34 }
35 }
36
37 public void setIfMissing(Tuple tuple, TruthValue truthValue) {
38 if (truthValue != null) {
39 root.setIfMissing(levels - 1, tuple, truthValue);
40 }
41 }
42
43 public void setAllMissing(TruthValue truthValue) {
44 if (truthValue != null) {
45 root.setAllMissing(truthValue);
30 } 46 }
31 root.mergeValue(levels - 1, tuple, truthValue);
32 } 47 }
33 48
34 public void overwriteValues(DecisionTree values) { 49 public void overwriteValues(DecisionTree values) {
35 root.overwriteValues(values.root); 50 root.overwriteValues(values.root);
36 } 51 }
37 52
53 public TruthValue getReducedValue() {
54 var reducedValue = root.getReducedValue();
55 return reducedValue == null ? null : reducedValue.getTruthValue();
56 }
57
38 public Cursor<Tuple, TruthValue> getCursor(TruthValue defaultValue, int nodeCount) { 58 public Cursor<Tuple, TruthValue> getCursor(TruthValue defaultValue, int nodeCount) {
39 return new DecisionTreeCursor(levels, defaultValue, nodeCount, root); 59 return new DecisionTreeCursor(levels, defaultValue, nodeCount, root);
40 } 60 }
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java
index 7f38fc79..8ca54969 100644
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java
+++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java
@@ -33,6 +33,24 @@ abstract class DecisionTreeNode {
33 return copy; 33 return copy;
34 } 34 }
35 35
36 public void setIfMissing(int level, Tuple tuple, TruthValue value) {
37 var key = tuple.get(level);
38 if (key < 0) {
39 throw new IllegalArgumentException("Not allowed set a missing wildcard");
40 }
41 doSetIfMissing(key, level - 1, tuple, value);
42 }
43
44 protected abstract void doSetIfMissing(int key, int nextLevel, Tuple tuple, TruthValue value);
45
46 public DecisionTreeNode withValueSetIfMissing(int level, Tuple tuple, TruthValue value) {
47 var copy = deepCopy();
48 copy.setIfMissing(level, tuple, value);
49 return copy;
50 }
51
52 public abstract void setAllMissing(TruthValue value);
53
36 public abstract void overwriteValues(DecisionTreeNode values); 54 public abstract void overwriteValues(DecisionTreeNode values);
37 55
38 public DecisionTreeNode withOverwrittenValues(DecisionTreeNode values) { 56 public DecisionTreeNode withOverwrittenValues(DecisionTreeNode values) {
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java
index 1bf3c8b8..993987f5 100644
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java
+++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java
@@ -19,14 +19,18 @@ public enum DecisionTreeValue {
19 return truthValue; 19 return truthValue;
20 } 20 }
21 21
22 public DecisionTreeValue merge(TruthValue other) { 22 public TruthValue merge(TruthValue other) {
23 return truthValue == null ? fromTruthValue(other) : fromTruthValue(truthValue.merge(other)); 23 return truthValue == null ? other : truthValue.merge(other);
24 } 24 }
25 25
26 public DecisionTreeValue overwrite(DecisionTreeValue other) { 26 public DecisionTreeValue overwrite(DecisionTreeValue other) {
27 return other == UNSET ? this : other; 27 return other == UNSET ? this : other;
28 } 28 }
29 29
30 public TruthValue getTruthValueOrElse(TruthValue other) {
31 return this == UNSET ? other : truthValue;
32 }
33
30 public static DecisionTreeValue fromTruthValue(TruthValue truthValue) { 34 public static DecisionTreeValue fromTruthValue(TruthValue truthValue) {
31 if (truthValue == null) { 35 if (truthValue == null) {
32 return DecisionTreeValue.UNSET; 36 return DecisionTreeValue.UNSET;
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java
index 7165197c..a7486ecb 100644
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java
+++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java
@@ -62,19 +62,43 @@ final class IntermediateNode extends DecisionTreeNode {
62 } 62 }
63 63
64 @Override 64 @Override
65 public void overwriteValues(DecisionTreeNode values) { 65 protected void doSetIfMissing(int key, int nextLevel, Tuple tuple, TruthValue value) {
66 if (values instanceof IntermediateNode intermediateValues) { 66 var child = children.get(key);
67 otherwise.overwriteValues(intermediateValues.otherwise); 67 if (child == null) {
68 for (var pair : children.keyValuesView()) { 68 var otherwiseReducedValue = getOtherwiseReducedValue();
69 pair.getTwo().overwriteValues(intermediateValues.getChild(pair.getOne())); 69 if (otherwiseReducedValue != null && otherwiseReducedValue != DecisionTreeValue.UNSET) {
70 } 70 // Value already set.
71 for (var pair : intermediateValues.children.keyValuesView()) { 71 return;
72 children.getIfAbsentPut(pair.getOne(), () -> otherwise.withOverwrittenValues(pair.getTwo()));
73 } 72 }
74 reduceChildren(); 73 var newChild = otherwise.withValueSetIfMissing(nextLevel, tuple, value);
75 } else { 74 children.put(key, newChild);
75 return;
76 }
77 child.setIfMissing(nextLevel, tuple, value);
78 }
79
80 @Override
81 public void setAllMissing(TruthValue value) {
82 otherwise.setAllMissing(value);
83 for (var child : children) {
84 child.setAllMissing(value);
85 }
86 reduceChildren();
87 }
88
89 @Override
90 public void overwriteValues(DecisionTreeNode values) {
91 if (!(values instanceof IntermediateNode intermediateValues)) {
76 throw new IllegalArgumentException("Level mismatch"); 92 throw new IllegalArgumentException("Level mismatch");
77 } 93 }
94 otherwise.overwriteValues(intermediateValues.otherwise);
95 for (var pair : children.keyValuesView()) {
96 pair.getTwo().overwriteValues(intermediateValues.getChild(pair.getOne()));
97 }
98 for (var pair : intermediateValues.children.keyValuesView()) {
99 children.getIfAbsentPut(pair.getOne(), () -> otherwise.withOverwrittenValues(pair.getTwo()));
100 }
101 reduceChildren();
78 } 102 }
79 103
80 private void reduceChildren() { 104 private void reduceChildren() {
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java
index f3adea61..c0197e89 100644
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java
+++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java
@@ -8,18 +8,18 @@ import tools.refinery.store.tuple.Tuple;
8import tools.refinery.store.model.representation.TruthValue; 8import tools.refinery.store.model.representation.TruthValue;
9 9
10class TerminalNode extends DecisionTreeNode { 10class TerminalNode extends DecisionTreeNode {
11 private MutableIntObjectMap<DecisionTreeValue> children; 11 private MutableIntObjectMap<TruthValue> children;
12 12
13 private DecisionTreeValue otherwise; 13 private DecisionTreeValue otherwise;
14 14
15 TerminalNode(MutableIntObjectMap<DecisionTreeValue> children, DecisionTreeValue otherwise) { 15 TerminalNode(MutableIntObjectMap<TruthValue> children, DecisionTreeValue otherwise) {
16 this.children = children; 16 this.children = children;
17 this.otherwise = otherwise; 17 this.otherwise = otherwise;
18 } 18 }
19 19
20 private DecisionTreeValue getChild(int index) { 20 private DecisionTreeValue getChild(int index) {
21 var child = children.get(index); 21 var child = children.get(index);
22 return child == null ? otherwise : child; 22 return child == null ? otherwise : DecisionTreeValue.fromTruthValue(child);
23 } 23 }
24 24
25 @Override 25 @Override
@@ -41,7 +41,7 @@ class TerminalNode extends DecisionTreeNode {
41 41
42 @Override 42 @Override
43 protected void mergeAllValues(int nextLevel, Tuple tuple, TruthValue value) { 43 protected void mergeAllValues(int nextLevel, Tuple tuple, TruthValue value) {
44 otherwise = otherwise.merge(value); 44 otherwise = DecisionTreeValue.fromTruthValue(otherwise.merge(value));
45 children = IntObjectMaps.mutable.from(children.keyValuesView(), IntObjectPair::getOne, 45 children = IntObjectMaps.mutable.from(children.keyValuesView(), IntObjectPair::getOne,
46 pair -> pair.getTwo().merge(value)); 46 pair -> pair.getTwo().merge(value));
47 reduceChildren(); 47 reduceChildren();
@@ -50,7 +50,7 @@ class TerminalNode extends DecisionTreeNode {
50 @Override 50 @Override
51 protected void mergeSingleValue(int key, int nextLevel, Tuple tuple, TruthValue value) { 51 protected void mergeSingleValue(int key, int nextLevel, Tuple tuple, TruthValue value) {
52 var newChild = getChild(key).merge(value); 52 var newChild = getChild(key).merge(value);
53 if (newChild == otherwise) { 53 if (otherwise.getTruthValue() == newChild) {
54 children.remove(key); 54 children.remove(key);
55 } else { 55 } else {
56 children.put(key, newChild); 56 children.put(key, newChild);
@@ -58,25 +58,45 @@ class TerminalNode extends DecisionTreeNode {
58 } 58 }
59 59
60 @Override 60 @Override
61 public void overwriteValues(DecisionTreeNode values) { 61 public void setIfMissing(int level, Tuple tuple, TruthValue value) {
62 if (values instanceof TerminalNode terminalValues) { 62 assertLevel(level);
63 otherwise = otherwise.overwrite(terminalValues.otherwise); 63 super.setIfMissing(level, tuple, value);
64 children = IntObjectMaps.mutable.from(children.keyValuesView(), IntObjectPair::getOne, 64 }
65 pair -> pair.getTwo().overwrite(terminalValues.getChild(pair.getOne()))); 65
66 for (var pair : terminalValues.children.keyValuesView()) { 66 @Override
67 children.getIfAbsentPut(pair.getOne(), otherwise.overwrite(pair.getTwo())); 67 protected void doSetIfMissing(int key, int nextLevel, Tuple tuple, TruthValue value) {
68 } 68 if (otherwise == DecisionTreeValue.UNSET) {
69 children.getIfAbsentPut(key, value);
70 }
71 }
72
73 @Override
74 public void setAllMissing(TruthValue value) {
75 if (otherwise == DecisionTreeValue.UNSET) {
76 otherwise = DecisionTreeValue.fromTruthValue(value);
69 reduceChildren(); 77 reduceChildren();
70 } else { 78 }
79 }
80
81 @Override
82 public void overwriteValues(DecisionTreeNode values) {
83 if (!(values instanceof TerminalNode terminalValues)) {
71 throw new IllegalArgumentException("Level mismatch"); 84 throw new IllegalArgumentException("Level mismatch");
72 } 85 }
86 otherwise = otherwise.overwrite(terminalValues.otherwise);
87 children = IntObjectMaps.mutable.from(children.keyValuesView(), IntObjectPair::getOne,
88 pair -> terminalValues.getChild(pair.getOne()).getTruthValueOrElse(pair.getTwo()));
89 for (var pair : terminalValues.children.keyValuesView()) {
90 children.getIfAbsentPut(pair.getOne(), pair.getTwo());
91 }
92 reduceChildren();
73 } 93 }
74 94
75 private void reduceChildren() { 95 private void reduceChildren() {
76 var iterator = children.iterator(); 96 var iterator = children.iterator();
77 while (iterator.hasNext()) { 97 while (iterator.hasNext()) {
78 var child = iterator.next(); 98 var child = iterator.next();
79 if (child == otherwise) { 99 if (otherwise.getTruthValue() == child) {
80 iterator.remove(); 100 iterator.remove();
81 } 101 }
82 } 102 }