//----------------------------------------------------------------------------- // // 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(); } }