aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java
blob: 9daa8f61022fa8dd295e3f1ff2d073d79f60ad70 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
 * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/>
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package tools.refinery.language.utils;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.EcoreUtil2;
import tools.refinery.language.library.BuiltinLibrary;
import tools.refinery.language.model.problem.*;

public final class ProblemUtil {
	public static final String MODULE_EXTENSION = "refinery";

	private ProblemUtil() {
		throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
	}

	public static boolean isBuiltIn(EObject eObject) {
		if (eObject != null) {
			var eResource = eObject.eResource();
			if (eResource != null) {
				return BuiltinLibrary.BUILTIN_LIBRARY_URI.equals(eResource.getURI());
			}
		}
		return false;
	}

	public static boolean isSingletonVariable(Variable variable) {
		return variable.eContainingFeature() == ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__SINGLETON_VARIABLE;
	}

	public static boolean isImplicitVariable(Variable variable) {
		return variable instanceof ImplicitVariable;
	}

	public static boolean isImplicitNode(Node node) {
		return node.eContainingFeature() == ProblemPackage.Literals.PROBLEM__NODES;
	}

	public static boolean isImplicit(EObject eObject) {
		if (eObject instanceof Node node) {
			return isImplicitNode(node);
		} else if (eObject instanceof Variable variable) {
			return isImplicitVariable(variable);
		} else {
			return false;
		}
	}

	public static boolean isError(EObject eObject) {
		return eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isError();
	}

	public static boolean isAtomNode(Node node) {
		var containingFeature = node.eContainingFeature();
		if (containingFeature == ProblemPackage.Literals.NODE_DECLARATION__NODES) {
			return ((NodeDeclaration) node.eContainer()).getKind() == NodeKind.ATOM;
		}
		return containingFeature == ProblemPackage.Literals.ENUM_DECLARATION__LITERALS;
	}

	public static boolean isMultiNode(Node node) {
		var containingFeature = node.eContainingFeature();
		if (containingFeature == ProblemPackage.Literals.NODE_DECLARATION__NODES) {
			return ((NodeDeclaration) node.eContainer()).getKind() == NodeKind.MULTI;
		}
		return containingFeature == ProblemPackage.Literals.CLASS_DECLARATION__NEW_NODE;
	}

	public static boolean isDeclaredNode(Node node) {
		return node.eContainingFeature() == ProblemPackage.Literals.NODE_DECLARATION__NODES;
	}

	public static boolean isInvalidMultiplicityConstraint(PredicateDefinition predicateDefinition) {
		return predicateDefinition.eContainingFeature() ==
				ProblemPackage.Literals.REFERENCE_DECLARATION__INVALID_MULTIPLICITY;
	}

	public static boolean hasMultiplicityConstraint(ReferenceDeclaration referenceDeclaration) {
		if (referenceDeclaration.getReferenceType() instanceof DatatypeDeclaration) {
			return false;
		}
		var opposite = referenceDeclaration.getOpposite();
		if (opposite != null && opposite.getKind() == ReferenceKind.CONTAINMENT) {
			return false;
		}
		var multiplicity = referenceDeclaration.getMultiplicity();
		if (multiplicity instanceof UnboundedMultiplicity) {
			return false;
		}
		if (multiplicity instanceof RangeMultiplicity rangeMultiplicity) {
			return rangeMultiplicity.getLowerBound() > 0 || rangeMultiplicity.getUpperBound() >= 0;
		}
		return true;
	}

	public static boolean isTypeLike(Relation relation) {
		if (relation instanceof ClassDeclaration || relation instanceof EnumDeclaration ||
				relation instanceof DatatypeDeclaration) {
			return true;
		}
		if (relation instanceof PredicateDefinition predicateDefinition) {
			return predicateDefinition.getParameters().size() == 1;
		}
		return false;
	}

	public static boolean isContainmentReference(ReferenceDeclaration referenceDeclaration) {
		return referenceDeclaration.getKind() == ReferenceKind.CONTAINMENT;
	}

	public static boolean isContainerReference(ReferenceDeclaration referenceDeclaration) {
		var kind = referenceDeclaration.getKind();
		if (kind == null) {
			return false;
		}
		return switch (kind) {
			case CONTAINMENT -> false;
			case CONTAINER -> true;
			case DEFAULT, REFERENCE -> {
				var opposite = referenceDeclaration.getOpposite();
				if (opposite == null) {
					yield false;
				}
				opposite = (ReferenceDeclaration) EcoreUtil.resolve(opposite, referenceDeclaration);
				yield opposite.getKind() == ReferenceKind.CONTAINMENT;
			}
		};
	}

	public static ModuleKind getDefaultModuleKind(Problem problem) {
		var resource = problem.eResource();
		if (resource == null) {
			return ModuleKind.PROBLEM;
		}
		return getDefaultModuleKind(resource.getURI());
	}

	public static ModuleKind getDefaultModuleKind(URI uri) {
		return MODULE_EXTENSION.equals(uri.fileExtension()) ? ModuleKind.MODULE : ModuleKind.PROBLEM;
	}

	public static boolean isModule(Problem problem) {
		return problem.getKind() == ModuleKind.MODULE;
	}

	public static boolean isInModule(EObject eObject) {
		var problem = EcoreUtil2.getContainerOfType(eObject, Problem.class);
		return problem != null && isModule(problem);
	}
}