diff options
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.java | 112 |
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 @@ | |||
1 | package tools.refinery.store.query; | ||
2 | |||
3 | import tools.refinery.store.query.literal.CallPolarity; | ||
4 | import tools.refinery.store.query.literal.DnfCallLiteral; | ||
5 | import tools.refinery.store.query.literal.LiteralReduction; | ||
6 | |||
7 | import java.util.*; | ||
8 | |||
9 | public 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 | } | ||