using System.Numerics; using System.Collections.Generic; namespace Dafny { public class Set { Dictionary dict; public Set() { } Set(Dictionary d) { dict = d; } public static Set Empty { get { return new Set(new Dictionary(0)); } } public static Set FromElements(params T[] values) { Dictionary d = new Dictionary(values.Length); foreach (T t in values) d.Add(t, true); return new Set(d); } public IEnumerable Elements { get { return dict.Keys; } } public bool Equals(Set other) { return dict.Count == other.dict.Count && IsSubsetOf(other); } public override bool Equals(object other) { return other is Set && Equals((Set)other); } public override int GetHashCode() { return dict.GetHashCode(); } public bool IsProperSubsetOf(Set other) { return dict.Count < other.dict.Count && IsSubsetOf(other); } public bool IsSubsetOf(Set other) { if (other.dict.Count < dict.Count) return false; foreach (T t in dict.Keys) { if (!other.dict.ContainsKey(t)) return false; } return true; } public bool IsSupersetOf(Set other) { return other.IsSubsetOf(this); } public bool IsProperSupersetOf(Set other) { return other.IsProperSubsetOf(this); } public bool IsDisjointFrom(Set other) { Dictionary a, b; if (dict.Count < other.dict.Count) { a = dict; b = other.dict; } else { a = other.dict; b = dict; } foreach (T t in a.Keys) { if (b.ContainsKey(t)) return false; } return true; } public bool Contains(T t) { return dict.ContainsKey(t); } public Set Union(Set other) { if (dict.Count == 0) return other; else if (other.dict.Count == 0) return this; Dictionary a, b; if (dict.Count < other.dict.Count) { a = dict; b = other.dict; } else { a = other.dict; b = dict; } Dictionary r = new Dictionary(); foreach (T t in b.Keys) r[t] = true; foreach (T t in a.Keys) r[t] = true; return new Set(r); } public Set Intersect(Set other) { if (dict.Count == 0) return this; else if (other.dict.Count == 0) return other; Dictionary a, b; if (dict.Count < other.dict.Count) { a = dict; b = other.dict; } else { a = other.dict; b = dict; } Dictionary r = new Dictionary(); foreach (T t in a.Keys) { if (b.ContainsKey(t)) r.Add(t, true); } return new Set(r); } public Set Difference(Set other) { if (dict.Count == 0) return this; else if (other.dict.Count == 0) return this; Dictionary r = new Dictionary(); foreach (T t in dict.Keys) { if (!other.dict.ContainsKey(t)) r.Add(t, true); } return new Set(r); } public T Choose() { foreach (T t in dict.Keys) { // return the first one return t; } } } public class Sequence { T[] elmts; public Sequence() { } Sequence(T[] ee) { elmts = ee; } public static Sequence Empty { get { return new Sequence(new T[0]); } } public static Sequence FromElements(params T[] values) { return new Sequence(values); } public BigInteger Length { get { return new BigInteger(elmts.Length); } } public T[] Elements { get { return elmts; } } public T Select(BigInteger index) { return elmts[(int)index]; } public Sequence Update(BigInteger index, T t) { T[] a = (T[])elmts.Clone(); a[(int)index] = t; return new Sequence(a); } public bool Equals(Sequence other) { int n = elmts.Length; return n == other.elmts.Length && EqualUntil(other, n); } public override bool Equals(object other) { return other is Sequence && Equals((Sequence)other); } public override int GetHashCode() { return elmts.GetHashCode(); } bool EqualUntil(Sequence other, int n) { for (int i = 0; i < n; i++) { if (!elmts[i].Equals(other.elmts[i])) return false; } return true; } public bool IsProperPrefixOf(Sequence other) { int n = elmts.Length; return n < other.elmts.Length && EqualUntil(other, n); } public bool IsPrefixOf(Sequence other) { int n = elmts.Length; return n <= other.elmts.Length && EqualUntil(other, n); } public Sequence Concat(Sequence other) { if (elmts.Length == 0) return other; else if (other.elmts.Length == 0) return this; T[] a = new T[elmts.Length + other.elmts.Length]; System.Array.Copy(elmts, 0, a, 0, elmts.Length); System.Array.Copy(other.elmts, 0, a, elmts.Length, other.elmts.Length); return new Sequence(a); } public bool Contains(T t) { int n = elmts.Length; for (int i = 0; i < n; i++) { if (t.Equals(elmts[i])) return true; } return false; } public Sequence Take(BigInteger n) { int m = (int)n; if (elmts.Length == m) return this; T[] a = new T[m]; System.Array.Copy(elmts, a, m); return new Sequence(a); } public Sequence Drop(BigInteger n) { if (n.IsZero) return this; int m = (int)n; T[] a = new T[elmts.Length - m]; System.Array.Copy(elmts, m, a, 0, elmts.Length - m); return new Sequence(a); } } public struct Pair { public readonly A Car; public readonly B Cdr; public Pair(A a, B b) { this.Car = a; this.Cdr = b; } } public partial class Helpers { public static bool QuantBool(bool frall, System.Predicate pred) { if (frall) { return pred(false) && pred(true); } else { return pred(false) || pred(true); } } public static bool QuantInt(BigInteger lo, BigInteger hi, bool frall, System.Predicate pred) { for (BigInteger i = lo; i < hi; i++) { if (pred(i) != frall) { return !frall; } } return frall; } public static bool QuantSet(Dafny.Set set, bool frall, System.Predicate pred) { foreach (var t in set.Elements) { if (pred(t) != frall) { return !frall; } } return frall; } public static bool QuantSeq(Dafny.Sequence seq, bool frall, System.Predicate pred) { foreach (var t in seq.Elements) { if (pred(t) != frall) { return !frall; } } return frall; } } }