diff options
Diffstat (limited to 'subprojects/logic/src/main/java/tools/refinery/logic/substitution/SubstitutionBuilder.java')
-rw-r--r-- | subprojects/logic/src/main/java/tools/refinery/logic/substitution/SubstitutionBuilder.java | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/subprojects/logic/src/main/java/tools/refinery/logic/substitution/SubstitutionBuilder.java b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/SubstitutionBuilder.java new file mode 100644 index 00000000..f30b1a5d --- /dev/null +++ b/subprojects/logic/src/main/java/tools/refinery/logic/substitution/SubstitutionBuilder.java | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.logic.substitution; | ||
7 | |||
8 | import tools.refinery.logic.term.DataVariable; | ||
9 | import tools.refinery.logic.term.NodeVariable; | ||
10 | import tools.refinery.logic.term.Variable; | ||
11 | |||
12 | import java.util.Collections; | ||
13 | import java.util.HashMap; | ||
14 | import java.util.List; | ||
15 | import java.util.Map; | ||
16 | |||
17 | @SuppressWarnings("UnusedReturnValue") | ||
18 | public class SubstitutionBuilder { | ||
19 | private final Map<Variable, Variable> map = new HashMap<>(); | ||
20 | private Substitution fallback; | ||
21 | |||
22 | SubstitutionBuilder() { | ||
23 | total(); | ||
24 | } | ||
25 | |||
26 | public SubstitutionBuilder put(NodeVariable original, NodeVariable substitute) { | ||
27 | return putChecked(original, substitute); | ||
28 | } | ||
29 | |||
30 | public <T> SubstitutionBuilder put(DataVariable<T> original, DataVariable<T> substitute) { | ||
31 | return putChecked(original, substitute); | ||
32 | } | ||
33 | |||
34 | public SubstitutionBuilder putChecked(Variable original, Variable substitute) { | ||
35 | if (!original.tryGetType().equals(substitute.tryGetType())) { | ||
36 | throw new IllegalArgumentException("Cannot substitute variable %s of sort %s with variable %s of sort %s" | ||
37 | .formatted(original, original.tryGetType().map(Class::getName).orElse("node"), substitute, | ||
38 | substitute.tryGetType().map(Class::getName).orElse("node"))); | ||
39 | } | ||
40 | if (map.containsKey(original)) { | ||
41 | throw new IllegalArgumentException("Already has substitution for variable %s".formatted(original)); | ||
42 | } | ||
43 | map.put(original, substitute); | ||
44 | return this; | ||
45 | } | ||
46 | |||
47 | public SubstitutionBuilder putManyChecked(List<Variable> originals, List<Variable> substitutes) { | ||
48 | int size = originals.size(); | ||
49 | if (size != substitutes.size()) { | ||
50 | throw new IllegalArgumentException("Cannot substitute %d variables %s with %d variables %s" | ||
51 | .formatted(size, originals, substitutes.size(), substitutes)); | ||
52 | } | ||
53 | for (int i = 0; i < size; i++) { | ||
54 | putChecked(originals.get(i), substitutes.get(i)); | ||
55 | } | ||
56 | return this; | ||
57 | } | ||
58 | |||
59 | public SubstitutionBuilder fallback(Substitution newFallback) { | ||
60 | fallback = newFallback; | ||
61 | return this; | ||
62 | } | ||
63 | |||
64 | public SubstitutionBuilder total() { | ||
65 | return fallback(StatelessSubstitution.FAILING); | ||
66 | } | ||
67 | |||
68 | public SubstitutionBuilder partial() { | ||
69 | return fallback(StatelessSubstitution.IDENTITY); | ||
70 | } | ||
71 | |||
72 | public SubstitutionBuilder renewing() { | ||
73 | return fallback(new RenewingSubstitution()); | ||
74 | } | ||
75 | |||
76 | public Substitution build() { | ||
77 | return map.isEmpty() ? fallback : new MapBasedSubstitution(Collections.unmodifiableMap(map), fallback); | ||
78 | } | ||
79 | } | ||