-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathAbstractEnumerationFormulaManager.java
132 lines (111 loc) · 4.8 KB
/
AbstractEnumerationFormulaManager.java
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
// This file is part of JavaSMT,
// an API wrapper for a collection of SMT solvers:
// https://github.com/sosy-lab/java-smt
//
// SPDX-FileCopyrightText: 2023 Dirk Beyer <https://www.sosy-lab.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.sosy_lab.java_smt.basicimpl;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.sosy_lab.java_smt.basicimpl.AbstractFormulaManager.checkVariableName;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import org.sosy_lab.java_smt.api.BooleanFormula;
import org.sosy_lab.java_smt.api.EnumerationFormula;
import org.sosy_lab.java_smt.api.EnumerationFormulaManager;
import org.sosy_lab.java_smt.api.FormulaType;
import org.sosy_lab.java_smt.api.FormulaType.EnumerationFormulaType;
@SuppressWarnings("ClassTypeParameterName")
public abstract class AbstractEnumerationFormulaManager<TFormulaInfo, TType, TEnv, TFuncDecl>
extends AbstractBaseFormulaManager<TFormulaInfo, TType, TEnv, TFuncDecl>
implements EnumerationFormulaManager {
/** The class 'EnumType' is just a plain internal value-holding class. */
protected class EnumType {
private final EnumerationFormulaType enumerationFormulaType;
private final TType nativeType;
private final ImmutableMap<String, TFormulaInfo> constants;
public EnumType(
EnumerationFormulaType pEnumerationFormulaType,
TType pNativeType,
ImmutableMap<String, TFormulaInfo> pConstants) {
enumerationFormulaType = pEnumerationFormulaType;
nativeType = pNativeType;
constants = pConstants;
}
public EnumerationFormulaType getEnumerationFormulaType() {
return enumerationFormulaType;
}
public boolean hasConstants(String name) {
return constants.containsKey(name);
}
}
protected final Map<String, EnumType> enumerations = new LinkedHashMap<>();
protected AbstractEnumerationFormulaManager(
FormulaCreator<TFormulaInfo, TType, TEnv, TFuncDecl> pFormulaCreator) {
super(pFormulaCreator);
}
private EnumerationFormula wrap(TFormulaInfo pTerm) {
return getFormulaCreator().encapsulateEnumeration(pTerm);
}
private void checkSameEnumerationType(EnumerationFormula pF1, EnumerationFormula pF2) {
final FormulaType<?> type1 = formulaCreator.getFormulaType(pF1);
final FormulaType<?> type2 = formulaCreator.getFormulaType(pF2);
checkArgument(type1 instanceof EnumerationFormulaType);
checkArgument(type2 instanceof EnumerationFormulaType);
checkArgument(
type1.equals(type2),
"Can't compare element of type %s with element of type %s.",
type1,
type2);
}
@Override
public EnumerationFormulaType declareEnumeration(String pName, Set<String> pElementNames) {
checkVariableName(pName);
return declareEnumerationImpl(pName, pElementNames);
}
protected EnumerationFormulaType declareEnumerationImpl(String pName, Set<String> pElementNames) {
final EnumerationFormulaType type = FormulaType.getEnumerationType(pName, pElementNames);
EnumType existingType = enumerations.get(pName);
if (existingType == null) {
enumerations.put(pName, declareEnumeration0(type));
} else {
Preconditions.checkArgument(
type.equals(existingType.getEnumerationFormulaType()),
"Enumeration type '%s' is already declared as '%s'.",
type,
existingType.getEnumerationFormulaType());
}
return type;
}
protected abstract EnumType declareEnumeration0(EnumerationFormulaType pType);
@Override
public EnumerationFormula makeConstant(String pName, EnumerationFormulaType pType) {
Preconditions.checkArgument(
pType.getElements().contains(pName),
"Constant '%s' is not available in the enumeration type '%s'",
pName,
pType);
return wrap(makeConstantImpl(pName, pType));
}
protected TFormulaInfo makeConstantImpl(String pName, EnumerationFormulaType pType) {
return checkNotNull(enumerations.get(pType.getName()).constants.get(pName));
}
@Override
public EnumerationFormula makeVariable(String pVar, EnumerationFormulaType pType) {
checkVariableName(pVar);
return wrap(makeVariableImpl(pVar, pType));
}
protected TFormulaInfo makeVariableImpl(String pVar, EnumerationFormulaType pType) {
return getFormulaCreator().makeVariable(enumerations.get(pType.getName()).nativeType, pVar);
}
@Override
public BooleanFormula equivalence(EnumerationFormula pF1, EnumerationFormula pF2) {
this.checkSameEnumerationType(pF1, pF2);
return wrapBool(equivalenceImpl(extractInfo(pF1), extractInfo(pF2)));
}
protected abstract TFormulaInfo equivalenceImpl(TFormulaInfo pF1, TFormulaInfo pF2);
}