//-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
namespace Microsoft.Boogie
{
using System;
using System.IO;
using System.Collections;
using Microsoft.Contracts;
///
/// A class representing a mathematical set.
///
public class Set : ICloneable, IEnumerable
{
/*[Own]*/ Hashtable! ht;
public Set()
{
ht = new Hashtable();
base();
}
private Set(Hashtable! ht)
{
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)
{
ht[o] = o;
}
///
/// this.SetElements = this.SetElements_old \union s.SetElements;
///
public void AddRange(Set! s)
{
foreach (object! o in s)
{
Add(o);
}
}
///
/// this.SetElements = this.SetElements_old \setminus {o};
///
public void Remove(object! o)
{
ht.Remove(o);
}
///
/// this.SetElements = this.SetElements_old \setminus s.SetElements;
///
public void RemoveRange(Set! s)
{
if (s == this)
{
ht.Clear();
}
else
{
foreach (object! o in s)
{
ht.Remove(o);
}
}
}
///
/// Returns an arbitrary element from the set.
///
public object! Choose()
requires Count > 0;
{
IEnumerator iter = GetEnumerator();
iter.MoveNext();
return (!)iter.Current;
}
///
/// Picks an arbitrary element from the set, removes it, and returns it.
///
public object! Take()
requires Count > 0;
ensures Count == old(Count) - 1;
{
object r = Choose();
Remove(r);
return r;
}
public void Intersect(Set! s)
{
Hashtable h = new Hashtable(ht.Count);
foreach (object! key in ht.Keys)
{
if (s.ht.ContainsKey(key))
{
h.Add(key, key);
}
}
ht = h;
}
///
/// The getter returns true iff "o" is in the set.
/// The setter adds the value "o" (for "true") or removes "o" (for "false")
///
public bool this[object! o]
{
get
{
return ht.ContainsKey(o);
}
set
{
if (value) {
Add(o);
} else {
Remove(o);
}
}
}
///
/// Returns true iff "o" is an element of "this".
///
///
///
[Pure]
public bool Contains(object! o)
{
if (!this.ht.ContainsKey(o))
{
return false;
}
return true;
}
///
/// Returns true iff every element of "s" is an element of "this", that is, if
/// "s" is a subset of "this".
///
///
///
public bool ContainsRange(Set! s)
{
if (s != this)
{
foreach (object! key in s.ht.Keys)
{
if (!this.ht.ContainsKey(key))
{
return false;
}
}
}
return true;
}
public object! Clone()
{
return new Set((Hashtable!)ht.Clone());
}
public virtual int Count
{
get
{
return ht.Count;
}
}
[Pure]
public IEnumerator! GetEnumerator()
{
return ht.Keys.GetEnumerator();
}
[Pure]
public override string! ToString()
{
string s = null;
foreach (object! key in ht.Keys)
{
if (s == null)
{
s = "{";
}
else
{
s += ", ";
}
s += key.ToString();
}
if (s == null)
{
return "{}";
}
else
{
return s + "}";
}
}
public bool AddAll(IEnumerable! objs){
foreach (object! o in objs){
this.Add(o);
}
return true;
}
//----------------------------- Static Methods ---------------------------------
// Functional Intersect
public static Set! Intersect(Set! a, Set! b)
// ensures Forall{ object x in result; a[x] && b[x] };
{
Set! res = (Set!) a.Clone();
res.Intersect(b);
return res;
}
// Functional Union
public static Set! Union(Set! a, Set! b)
// ensures Forall{ object x in result; a[x] || b[x] };
{
Set! res = (Set!) a.Clone();
res.AddRange(b);
return res;
}
public delegate bool SetFilter(object! obj);
public static Set! Filter(Set! a, SetFilter! filter)
{
Set inter = new Set();
foreach(object! elem in a)
{
if (filter(elem))
{
inter.Add(elem);
}
}
return inter;
}
}
public interface IWorkList: ICollection
{
bool Add(object o);
bool AddAll(IEnumerable objs);
bool IsEmpty();
object Pull();
}
}