//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
namespace Microsoft.Boogie {
using System;
using System.IO;
using System.Collections;
using System.Diagnostics.Contracts;
///
/// A class representing a mathematical set.
///
public class Set : ICloneable, IEnumerable {
/*[Own]*/
Hashtable ht;
[ContractInvariantMethod]
void ObjectInvariant() {
Contract.Invariant(ht != null);
}
public Set() {
ht = new Hashtable();
//:base();
}
private Set(Hashtable/*!*/ ht) {
Contract.Requires(ht != null);
this.ht = ht;
//:base();
}
public Set(int capacity) {
ht = new Hashtable(capacity);
//:base();
}
public readonly static Set/*!*/ Empty = new Set();
public void Clear() {
ht.Clear();
}
///
/// This method idempotently adds "o" to the set.
/// In notation:
/// this.SetElements = this.SetElements_old \union {o};
///
public void Add(object/*!*/ o) {
Contract.Requires(o != null);
ht[o] = o;
}
///
/// this.SetElements = this.SetElements_old \union s.SetElements;
///
public void AddRange(Set/*!*/ s) {
Contract.Requires(s != null);
foreach (object/*!*/ o in s) {
Contract.Assert(o != null);
Add(o);
}
}
///
/// this.SetElements = this.SetElements_old \setminus {o};
///
public void Remove(object/*!*/ o) {
Contract.Requires(o != null);
ht.Remove(o);
}
///
/// this.SetElements = this.SetElements_old \setminus s.SetElements;
///
public void RemoveRange(Set/*!*/ s) {
Contract.Requires(s != null);
if (s == this) {
ht.Clear();
} else {
foreach (object/*!*/ o in s) {
Contract.Assert(o != null);
ht.Remove(o);
}
}
}
///
/// Returns an arbitrary element from the set.
///
public object/*!*/ Choose() {
Contract.Requires((Count > 0));
Contract.Ensures(Contract.Result