aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-06-22 21:52:53 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-06-22 22:03:13 +0200
commitf2ab0e12838efe5a23abb79fd7228f89dc3ba8ef (patch)
treea11fe1e4663563dfee094aae08fc03cbbab89839
parentrefactor: remove Rule (diff)
downloadrefinery-f2ab0e12838efe5a23abb79fd7228f89dc3ba8ef.tar.gz
refinery-f2ab0e12838efe5a23abb79fd7228f89dc3ba8ef.tar.zst
refinery-f2ab0e12838efe5a23abb79fd7228f89dc3ba8ef.zip
fix: FilteredView default value
The filer can't return true for the default value, because tuples with default value cannot be enumerated.
-rw-r--r--subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java72
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java20
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java21
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java2
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/KeyOnlyView.java4
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java2
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java2
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/view/SymbolView.java9
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMayTypeView.java18
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMustTypeView.java18
10 files changed, 146 insertions, 22 deletions
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java
index 297cdf04..25bcb0dc 100644
--- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java
+++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java
@@ -572,6 +572,78 @@ class QueryTest {
572 ), predicateResultSet); 572 ), predicateResultSet);
573 } 573 }
574 574
575 @Test
576 void filteredIntegerViewTest() {
577 var distance = Symbol.of("distance", 2, Integer.class);
578 var nearView = new FilteredView<>(distance, value -> value < 2);
579 var farView = new FilteredView<>(distance, value -> value >= 5);
580 var dangerQuery = Query.of("danger", (builder, a1, a2) -> builder.clause((a3) -> List.of(
581 a1.notEquivalent(a2),
582 nearView.call(a1, a3),
583 nearView.call(a2, a3),
584 not(farView.call(a1, a2))
585 )));
586 var store = ModelStore.builder()
587 .symbols(distance)
588 .with(ViatraModelQueryAdapter.builder()
589 .queries(dangerQuery))
590 .build();
591
592 var model = store.createEmptyModel();
593 var distanceInterpretation = model.getInterpretation(distance);
594 distanceInterpretation.put(Tuple.of(0, 1), 1);
595 distanceInterpretation.put(Tuple.of(1, 0), 1);
596 distanceInterpretation.put(Tuple.of(0, 2), 1);
597 distanceInterpretation.put(Tuple.of(2, 0), 1);
598 distanceInterpretation.put(Tuple.of(1, 2), 3);
599 distanceInterpretation.put(Tuple.of(2, 1), 3);
600 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
601 var dangerResultSet = queryEngine.getResultSet(dangerQuery);
602 queryEngine.flushChanges();
603 assertResults(Map.of(
604 Tuple.of(0, 1), false,
605 Tuple.of(0, 2), false,
606 Tuple.of(1, 2), true,
607 Tuple.of(2, 1), true
608 ), dangerResultSet);
609 }
610
611 @Test
612 void filteredDoubleViewTest() {
613 var distance = Symbol.of("distance", 2, Double.class);
614 var nearView = new FilteredView<>(distance, value -> value < 2);
615 var farView = new FilteredView<>(distance, value -> value >= 5);
616 var dangerQuery = Query.of("danger", (builder, a1, a2) -> builder.clause((a3) -> List.of(
617 a1.notEquivalent(a2),
618 nearView.call(a1, a3),
619 nearView.call(a2, a3),
620 not(farView.call(a1, a2))
621 )));
622 var store = ModelStore.builder()
623 .symbols(distance)
624 .with(ViatraModelQueryAdapter.builder()
625 .queries(dangerQuery))
626 .build();
627
628 var model = store.createEmptyModel();
629 var distanceInterpretation = model.getInterpretation(distance);
630 distanceInterpretation.put(Tuple.of(0, 1), 1.0);
631 distanceInterpretation.put(Tuple.of(1, 0), 1.0);
632 distanceInterpretation.put(Tuple.of(0, 2), 1.0);
633 distanceInterpretation.put(Tuple.of(2, 0), 1.0);
634 distanceInterpretation.put(Tuple.of(1, 2), 3.0);
635 distanceInterpretation.put(Tuple.of(2, 1), 3.0);
636 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
637 var dangerResultSet = queryEngine.getResultSet(dangerQuery);
638 queryEngine.flushChanges();
639 assertResults(Map.of(
640 Tuple.of(0, 1), false,
641 Tuple.of(0, 2), false,
642 Tuple.of(1, 2), true,
643 Tuple.of(2, 1), true
644 ), dangerResultSet);
645 }
646
575 @QueryEngineTest 647 @QueryEngineTest
576 void assumeTest(QueryEvaluationHint hint) { 648 void assumeTest(QueryEvaluationHint hint) {
577 var age = Symbol.of("age", 1, Integer.class); 649 var age = Symbol.of("age", 1, Integer.class);
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java
index c1f9d688..fd37604e 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/AbstractFunctionView.java
@@ -20,12 +20,10 @@ import java.util.stream.Collectors;
20import java.util.stream.IntStream; 20import java.util.stream.IntStream;
21 21
22public abstract class AbstractFunctionView<T> extends SymbolView<T> { 22public abstract class AbstractFunctionView<T> extends SymbolView<T> {
23 private final T defaultValue;
24 private final List<Parameter> parameters; 23 private final List<Parameter> parameters;
25 24
26 protected AbstractFunctionView(Symbol<T> symbol, String name, Parameter outParameter) { 25 protected AbstractFunctionView(Symbol<T> symbol, String name, Parameter outParameter) {
27 super(symbol, name); 26 super(symbol, name);
28 defaultValue = symbol.defaultValue();
29 parameters = createParameters(symbol.arity(), outParameter); 27 parameters = createParameters(symbol.arity(), outParameter);
30 } 28 }
31 29
@@ -46,16 +44,16 @@ public abstract class AbstractFunctionView<T> extends SymbolView<T> {
46 } 44 }
47 45
48 @Override 46 @Override
49 public final boolean filter(Tuple key, T value) { 47 protected boolean doFilter(Tuple key, T value) {
50 return !Objects.equals(defaultValue, value); 48 return true;
51 } 49 }
52 50
53 protected Object forwardMapValue(Tuple key, T value) { 51 protected Object forwardMapValue(T value) {
54 return value; 52 return value;
55 } 53 }
56 54
57 protected boolean valueEquals(Tuple key, T value, Object otherForwardMappedValue) { 55 protected boolean valueEquals(T value, Object otherForwardMappedValue) {
58 return Objects.equals(otherForwardMappedValue, forwardMapValue(key, value)); 56 return Objects.equals(otherForwardMappedValue, forwardMapValue(value));
59 } 57 }
60 58
61 @Override 59 @Override
@@ -65,7 +63,7 @@ public abstract class AbstractFunctionView<T> extends SymbolView<T> {
65 for (int i = 0; i < size; i++) { 63 for (int i = 0; i < size; i++) {
66 result[i] = Tuple.of(key.get(i)); 64 result[i] = Tuple.of(key.get(i));
67 } 65 }
68 result[key.getSize()] = forwardMapValue(key, value); 66 result[key.getSize()] = forwardMapValue(value);
69 return result; 67 return result;
70 } 68 }
71 69
@@ -81,7 +79,7 @@ public abstract class AbstractFunctionView<T> extends SymbolView<T> {
81 Tuple key = Tuple.of(content); 79 Tuple key = Tuple.of(content);
82 var valueInTuple = tuple[tuple.length - 1]; 80 var valueInTuple = tuple[tuple.length - 1];
83 T valueInMap = model.getInterpretation(getSymbol()).get(key); 81 T valueInMap = model.getInterpretation(getSymbol()).get(key);
84 return valueEquals(key, valueInMap, valueInTuple); 82 return valueEquals(valueInMap, valueInTuple);
85 } 83 }
86 84
87 @Override 85 @Override
@@ -95,12 +93,12 @@ public abstract class AbstractFunctionView<T> extends SymbolView<T> {
95 if (o == null || getClass() != o.getClass()) return false; 93 if (o == null || getClass() != o.getClass()) return false;
96 if (!super.equals(o)) return false; 94 if (!super.equals(o)) return false;
97 AbstractFunctionView<?> that = (AbstractFunctionView<?>) o; 95 AbstractFunctionView<?> that = (AbstractFunctionView<?>) o;
98 return Objects.equals(defaultValue, that.defaultValue) && Objects.equals(parameters, that.parameters); 96 return Objects.equals(parameters, that.parameters);
99 } 97 }
100 98
101 @Override 99 @Override
102 public int hashCode() { 100 public int hashCode() {
103 return Objects.hash(super.hashCode(), defaultValue, parameters); 101 return Objects.hash(super.hashCode(), parameters);
104 } 102 }
105 103
106 private static List<Parameter> createParameters(int symbolArity, Parameter outParameter) { 104 private static List<Parameter> createParameters(int symbolArity, Parameter outParameter) {
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java
index 922c7355..abae6e5c 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/FilteredView.java
@@ -27,14 +27,16 @@ public class FilteredView<T> extends TuplePreservingView<T> {
27 27
28 public FilteredView(Symbol<T> symbol, String name, Predicate<T> predicate) { 28 public FilteredView(Symbol<T> symbol, String name, Predicate<T> predicate) {
29 this(symbol, name, (k, v) -> predicate.test(v)); 29 this(symbol, name, (k, v) -> predicate.test(v));
30 validateDefaultValue(predicate);
30 } 31 }
31 32
32 public FilteredView(Symbol<T> symbol, Predicate<T> predicate) { 33 public FilteredView(Symbol<T> symbol, Predicate<T> predicate) {
33 this(symbol, (k, v) -> predicate.test(v)); 34 this(symbol, (k, v) -> predicate.test(v));
35 validateDefaultValue(predicate);
34 } 36 }
35 37
36 @Override 38 @Override
37 public boolean filter(Tuple key, T value) { 39 protected boolean doFilter(Tuple key, T value) {
38 return this.predicate.test(key, value); 40 return this.predicate.test(key, value);
39 } 41 }
40 42
@@ -51,4 +53,21 @@ public class FilteredView<T> extends TuplePreservingView<T> {
51 public int hashCode() { 53 public int hashCode() {
52 return Objects.hash(super.hashCode(), predicate); 54 return Objects.hash(super.hashCode(), predicate);
53 } 55 }
56
57 private void validateDefaultValue(Predicate<T> predicate) {
58 var defaultValue = getSymbol().defaultValue();
59 boolean matchesDefaultValue = false;
60 try {
61 matchesDefaultValue = predicate.test(defaultValue);
62 } catch (NullPointerException e) {
63 if (defaultValue != null) {
64 throw e;
65 }
66 // The predicate doesn't need to handle the default value if it is null.
67 }
68 if (matchesDefaultValue) {
69 throw new IllegalArgumentException("Tuples with default value %s cannot be enumerated in %s"
70 .formatted(defaultValue, getSymbol()));
71 }
72 }
54} 73}
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java
index 26b717ee..c312330e 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/ForbiddenView.java
@@ -15,7 +15,7 @@ public class ForbiddenView extends TuplePreservingView<TruthValue> {
15 } 15 }
16 16
17 @Override 17 @Override
18 public boolean filter(Tuple key, TruthValue value) { 18 protected boolean doFilter(Tuple key, TruthValue value) {
19 return !value.may(); 19 return !value.may();
20 } 20 }
21} 21}
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/KeyOnlyView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/KeyOnlyView.java
index 7e86f6e4..f0e4a61e 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/KeyOnlyView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/KeyOnlyView.java
@@ -21,8 +21,8 @@ public final class KeyOnlyView<T> extends TuplePreservingView<T> {
21 } 21 }
22 22
23 @Override 23 @Override
24 public boolean filter(Tuple key, T value) { 24 protected boolean doFilter(Tuple key, T value) {
25 return !Objects.equals(value, defaultValue); 25 return true;
26 } 26 }
27 27
28 @Override 28 @Override
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java
index e75a8171..c322e220 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MayView.java
@@ -15,7 +15,7 @@ public class MayView extends TuplePreservingView<TruthValue> {
15 } 15 }
16 16
17 @Override 17 @Override
18 public boolean filter(Tuple key, TruthValue value) { 18 protected boolean doFilter(Tuple key, TruthValue value) {
19 return value.may(); 19 return value.may();
20 } 20 }
21} 21}
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java
index a48f8045..65bb4e4c 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/MustView.java
@@ -15,7 +15,7 @@ public class MustView extends TuplePreservingView<TruthValue> {
15 } 15 }
16 16
17 @Override 17 @Override
18 public boolean filter(Tuple key, TruthValue value) { 18 protected boolean doFilter(Tuple key, TruthValue value) {
19 return value.must(); 19 return value.must();
20 } 20 }
21} 21}
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/SymbolView.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/SymbolView.java
index 267a99d3..cd8bd56b 100644
--- a/subprojects/store-query/src/main/java/tools/refinery/store/query/view/SymbolView.java
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/view/SymbolView.java
@@ -21,7 +21,6 @@ import java.util.UUID;
21 */ 21 */
22public abstract non-sealed class SymbolView<T> implements AnySymbolView { 22public abstract non-sealed class SymbolView<T> implements AnySymbolView {
23 private final Symbol<T> symbol; 23 private final Symbol<T> symbol;
24
25 private final String viewName; 24 private final String viewName;
26 25
27 protected SymbolView(Symbol<T> symbol, String viewName) { 26 protected SymbolView(Symbol<T> symbol, String viewName) {
@@ -48,7 +47,11 @@ public abstract non-sealed class SymbolView<T> implements AnySymbolView {
48 return symbol.name() + "#" + viewName; 47 return symbol.name() + "#" + viewName;
49 } 48 }
50 49
51 public abstract boolean filter(Tuple key, T value); 50 public final boolean filter(Tuple key, T value) {
51 return !Objects.equals(symbol.defaultValue(), value) && doFilter(key, value);
52 }
53
54 protected abstract boolean doFilter(Tuple key, T value);
52 55
53 public abstract Object[] forwardMap(Tuple key, T value); 56 public abstract Object[] forwardMap(Tuple key, T value);
54 57
@@ -77,6 +80,6 @@ public abstract non-sealed class SymbolView<T> implements AnySymbolView {
77 80
78 @Override 81 @Override
79 public int hashCode() { 82 public int hashCode() {
80 return Objects.hash(symbol, viewName); 83 return Objects.hash(getClass(), symbol, viewName);
81 } 84 }
82} 85}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMayTypeView.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMayTypeView.java
index ce2d6ff3..40de4644 100644
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMayTypeView.java
+++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMayTypeView.java
@@ -9,6 +9,8 @@ import tools.refinery.store.reasoning.representation.PartialRelation;
9import tools.refinery.store.query.view.TuplePreservingView; 9import tools.refinery.store.query.view.TuplePreservingView;
10import tools.refinery.store.tuple.Tuple; 10import tools.refinery.store.tuple.Tuple;
11 11
12import java.util.Objects;
13
12class InferredMayTypeView extends TuplePreservingView<InferredType> { 14class InferredMayTypeView extends TuplePreservingView<InferredType> {
13 private final PartialRelation type; 15 private final PartialRelation type;
14 16
@@ -18,7 +20,21 @@ class InferredMayTypeView extends TuplePreservingView<InferredType> {
18 } 20 }
19 21
20 @Override 22 @Override
21 public boolean filter(Tuple key, InferredType value) { 23 protected boolean doFilter(Tuple key, InferredType value) {
22 return value.mayConcreteTypes().contains(type); 24 return value.mayConcreteTypes().contains(type);
23 } 25 }
26
27 @Override
28 public boolean equals(Object o) {
29 if (this == o) return true;
30 if (o == null || getClass() != o.getClass()) return false;
31 if (!super.equals(o)) return false;
32 InferredMayTypeView that = (InferredMayTypeView) o;
33 return Objects.equals(type, that.type);
34 }
35
36 @Override
37 public int hashCode() {
38 return Objects.hash(super.hashCode(), type);
39 }
24} 40}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMustTypeView.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMustTypeView.java
index beda1796..1a121547 100644
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMustTypeView.java
+++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMustTypeView.java
@@ -9,6 +9,8 @@ import tools.refinery.store.reasoning.representation.PartialRelation;
9import tools.refinery.store.query.view.TuplePreservingView; 9import tools.refinery.store.query.view.TuplePreservingView;
10import tools.refinery.store.tuple.Tuple; 10import tools.refinery.store.tuple.Tuple;
11 11
12import java.util.Objects;
13
12class InferredMustTypeView extends TuplePreservingView<InferredType> { 14class InferredMustTypeView extends TuplePreservingView<InferredType> {
13 private final PartialRelation type; 15 private final PartialRelation type;
14 16
@@ -18,7 +20,21 @@ class InferredMustTypeView extends TuplePreservingView<InferredType> {
18 } 20 }
19 21
20 @Override 22 @Override
21 public boolean filter(Tuple key, InferredType value) { 23 protected boolean doFilter(Tuple key, InferredType value) {
22 return value.mustTypes().contains(type); 24 return value.mustTypes().contains(type);
23 } 25 }
26
27 @Override
28 public boolean equals(Object o) {
29 if (this == o) return true;
30 if (o == null || getClass() != o.getClass()) return false;
31 if (!super.equals(o)) return false;
32 InferredMustTypeView that = (InferredMustTypeView) o;
33 return Objects.equals(type, that.type);
34 }
35
36 @Override
37 public int hashCode() {
38 return Objects.hash(super.hashCode(), type);
39 }
24} 40}