dafny.DafnyMap Maven / Gradle / Ivy
// Copyright by the contributors to the Dafny Project
// SPDX-License-Identifier: MIT
package dafny;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
public class DafnyMap {
private Map innerMap;
public DafnyMap() {
innerMap = new HashMap<>();
}
private DafnyMap(HashMap innerMap) {
this.innerMap = innerMap;
}
public DafnyMap(Map m) {
assert m != null : "Precondition Violation";
innerMap = new HashMap<>();
m.forEach((k, v) -> innerMap.put(k, v));
}
public static DafnyMap empty() { return new DafnyMap(); }
@SuppressWarnings("unchecked")
public static DafnyMap fromElements(Tuple2 ... pairs) {
DafnyMap result = new DafnyMap();
for (Tuple2 pair : pairs) {
result.innerMap.put(pair.dtor__0(), pair.dtor__1());
}
return result;
}
@SuppressWarnings("unchecked")
public static TypeDescriptor> _typeDescriptor(
TypeDescriptor keyType, TypeDescriptor valueType) {
// Fudge the type parameters; it's not great, but it's safe because
// (for now) type descriptors are only used for default values
return TypeDescriptor.referenceWithDefault(
(Class>) (Class>) DafnyMap.class,
DafnyMap.empty());
}
public boolean contains(Object t) {
return innerMap.containsKey(t);
}
public static DafnyMap update(DafnyMap extends K, ? extends V> th, K k, V v) {
HashMap copy = new HashMap<>(th.innerMap);
copy.put(k, v);
DafnyMap r = new DafnyMap<>();
r.innerMap = copy;
return r;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
DafnyMap o = (DafnyMap) obj;
return innerMap.equals(o.innerMap);
}
@Override
public int hashCode() {
return innerMap.hashCode();
}
@Override
public String toString() {
String s = "map[";
String sep = "";
for (Map.Entry entry : innerMap.entrySet()) {
s += sep + Helpers.toString(entry.getKey()) + " := " + Helpers.toString(entry.getValue());
sep = ", ";
}
return s + "]";
}
public void forEach(BiConsumer super K, ? super V> action) {
innerMap.forEach(action);
}
@SuppressWarnings("unchecked")
public static DafnyMap extends K, ? extends V> merge(DafnyMap extends K, ? extends V> th, DafnyMap extends K, ? extends V> other) {
assert th != null : "Precondition Violation";
assert other != null : "Precondition Violation";
if (th.isEmpty()) {
return (DafnyMap)other;
} else if (other.isEmpty()) {
return (DafnyMap)th;
}
Map m = new HashMap(other.innerMap);
th.forEach((k, v) -> {
if (!m.containsKey(k)) {
m.put(k, v);
}
});
return new DafnyMap(m);
}
@SuppressWarnings("unchecked")
public static DafnyMap extends K, ? extends V> subtract(DafnyMap extends K, ? extends V> th, DafnySet extends K> keys) {
assert th != null : "Precondition Violation";
assert keys != null : "Precondition Violation";
if (th.isEmpty() || keys.isEmpty()) {
return (DafnyMap)th;
}
Map m = new HashMap(th.innerMap);
for (K k : keys.Elements()) {
m.remove(k);
}
return new DafnyMap(m);
}
public int size() {
return innerMap.size();
}
public int cardinalityInt() {
return size();
}
public boolean isEmpty() {
return innerMap.isEmpty();
}
public V get(Object key) {
return innerMap.get(key);
}
public DafnySet keySet() {
return new DafnySet<>(innerMap.keySet());
}
public DafnySet valueSet() {
return new DafnySet<>(innerMap.values());
}
// Until tuples (and other datatypes) are compiled with type-argument variance, the following
// method takes type parameters . The expectation is that is extends KK, ? extends VV>.
@SuppressWarnings("unchecked")
public DafnySet extends Tuple2> entrySet() {
ArrayList> list = new ArrayList>();
for (Map.Entry entry : innerMap.entrySet()) {
list.add(new Tuple2(entry.getKey(), entry.getValue()));
}
return (DafnySet extends Tuple2>)(Object)new DafnySet>(list);
}
}