aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query/src/main/java/tools/refinery/store/query/Dnf.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-query/src/main/java/tools/refinery/store/query/Dnf.java')
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/Dnf.java112
1 files changed, 112 insertions, 0 deletions
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/Dnf.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/Dnf.java
new file mode 100644
index 00000000..760b264b
--- /dev/null
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/Dnf.java
@@ -0,0 +1,112 @@
1package tools.refinery.store.query;
2
3import tools.refinery.store.query.literal.CallPolarity;
4import tools.refinery.store.query.literal.DnfCallLiteral;
5import tools.refinery.store.query.literal.LiteralReduction;
6
7import java.util.*;
8
9public final class Dnf implements RelationLike {
10 private final String name;
11
12 private final String uniqueName;
13
14 private final List<Variable> parameters;
15
16 private final List<FunctionalDependency<Variable>> functionalDependencies;
17
18 private final List<DnfClause> clauses;
19
20 Dnf(String name, List<Variable> parameters, List<FunctionalDependency<Variable>> functionalDependencies,
21 List<DnfClause> clauses) {
22 validateFunctionalDependencies(parameters, functionalDependencies);
23 this.name = name;
24 this.uniqueName = DnfUtils.generateUniqueName(name);
25 this.parameters = parameters;
26 this.functionalDependencies = functionalDependencies;
27 this.clauses = clauses;
28 }
29
30 private static void validateFunctionalDependencies(
31 Collection<Variable> parameters, Collection<FunctionalDependency<Variable>> functionalDependencies) {
32 var parameterSet = new HashSet<>(parameters);
33 for (var functionalDependency : functionalDependencies) {
34 validateParameters(parameters, parameterSet, functionalDependency.forEach(), functionalDependency);
35 validateParameters(parameters, parameterSet, functionalDependency.unique(), functionalDependency);
36 }
37 }
38
39 private static void validateParameters(Collection<Variable> parameters, Set<Variable> parameterSet,
40 Collection<Variable> toValidate,
41 FunctionalDependency<Variable> functionalDependency) {
42 for (var variable : toValidate) {
43 if (!parameterSet.contains(variable)) {
44 throw new IllegalArgumentException(
45 "Variable %s of functional dependency %s does not appear in the parameter list %s"
46 .formatted(variable, functionalDependency, parameters));
47 }
48 }
49 }
50
51 @Override
52 public String name() {
53 return name;
54 }
55
56 public String getUniqueName() {
57 return uniqueName;
58 }
59
60 public List<Variable> getParameters() {
61 return parameters;
62 }
63
64 public List<FunctionalDependency<Variable>> getFunctionalDependencies() {
65 return functionalDependencies;
66 }
67
68 @Override
69 public int arity() {
70 return parameters.size();
71 }
72
73 public List<DnfClause> getClauses() {
74 return clauses;
75 }
76
77 public LiteralReduction getReduction() {
78 if (clauses.isEmpty()) {
79 return LiteralReduction.ALWAYS_FALSE;
80 }
81 for (var clause : clauses) {
82 if (clause.literals().isEmpty()) {
83 return LiteralReduction.ALWAYS_TRUE;
84 }
85 }
86 return LiteralReduction.NOT_REDUCIBLE;
87 }
88
89 public DnfCallLiteral call(CallPolarity polarity, List<Variable> arguments) {
90 return new DnfCallLiteral(polarity, this, arguments);
91 }
92
93 public DnfCallLiteral call(CallPolarity polarity, Variable... arguments) {
94 return call(polarity, List.of(arguments));
95 }
96
97 public DnfCallLiteral call(Variable... arguments) {
98 return call(CallPolarity.POSITIVE, arguments);
99 }
100
101 public DnfCallLiteral callTransitive(Variable left, Variable right) {
102 return call(CallPolarity.TRANSITIVE, List.of(left, right));
103 }
104
105 public static DnfBuilder builder() {
106 return builder(null);
107 }
108
109 public static DnfBuilder builder(String name) {
110 return new DnfBuilder(name);
111 }
112}