From bd50fd6c2f2e042bc895d06ad6990bf0ee34cda4 Mon Sep 17 00:00:00 2001 From: Rustan Leino Date: Thu, 4 Oct 2012 15:35:12 -0700 Subject: Fixed some build/migration issues --- Binaries/DafnyRuntime.cs | 574 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 574 insertions(+) create mode 100644 Binaries/DafnyRuntime.cs (limited to 'Binaries/DafnyRuntime.cs') diff --git a/Binaries/DafnyRuntime.cs b/Binaries/DafnyRuntime.cs new file mode 100644 index 00000000..ac688143 --- /dev/null +++ b/Binaries/DafnyRuntime.cs @@ -0,0 +1,574 @@ +using System.Numerics; + +namespace Dafny +{ + using System.Collections.Generic; + + 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[t] = true; + return new Set(d); + } + public static Set FromCollection(ICollection values) { + Dictionary d = new Dictionary(); + foreach (T t in values) + d[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; + } + var 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; + var 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; + } + return default(T); + } + } + public class MultiSet + { + Dictionary dict; + public MultiSet() { } + MultiSet(Dictionary d) { + dict = d; + } + public static MultiSet Empty { + get { + return new MultiSet(new Dictionary(0)); + } + } + public static MultiSet FromElements(params T[] values) { + Dictionary d = new Dictionary(values.Length); + foreach (T t in values) { + var i = 0; + if (!d.TryGetValue(t, out i)) { + i = 0; + } + d[t] = i + 1; + } + return new MultiSet(d); + } + public static MultiSet FromCollection(ICollection values) { + Dictionary d = new Dictionary(); + foreach (T t in values) { + var i = 0; + if (!d.TryGetValue(t, out i)) { + i = 0; + } + d[t] = i + 1; + } + return new MultiSet(d); + } + public static MultiSet FromSeq(Sequence values) { + Dictionary d = new Dictionary(); + foreach (T t in values.Elements) { + var i = 0; + if (!d.TryGetValue(t, out i)) { + i = 0; + } + d[t] = i + 1; + } + return new MultiSet(d); + } + public static MultiSet FromSet(Set values) { + Dictionary d = new Dictionary(); + foreach (T t in values.Elements) { + d[t] = 1; + } + return new MultiSet(d); + } + + public bool Equals(MultiSet other) { + return other.IsSubsetOf(this) && this.IsSubsetOf(other); + } + public override bool Equals(object other) { + return other is MultiSet && Equals((MultiSet)other); + } + public override int GetHashCode() { + return dict.GetHashCode(); + } + public bool IsProperSubsetOf(MultiSet other) { + return !Equals(other) && IsSubsetOf(other); + } + public bool IsSubsetOf(MultiSet other) { + foreach (T t in dict.Keys) { + if (!other.dict.ContainsKey(t) || other.dict[t] < dict[t]) + return false; + } + return true; + } + public bool IsSupersetOf(MultiSet other) { + return other.IsSubsetOf(this); + } + public bool IsProperSupersetOf(MultiSet other) { + return other.IsProperSubsetOf(this); + } + public bool IsDisjointFrom(MultiSet other) { + foreach (T t in dict.Keys) { + if (other.dict.ContainsKey(t)) + return false; + } + foreach (T t in other.dict.Keys) { + if (dict.ContainsKey(t)) + return false; + } + return true; + } + public bool Contains(T t) { + return dict.ContainsKey(t); + } + public MultiSet Union(MultiSet other) { + if (dict.Count == 0) + return other; + else if (other.dict.Count == 0) + return this; + var r = new Dictionary(); + foreach (T t in dict.Keys) { + var i = 0; + if (!r.TryGetValue(t, out i)) { + i = 0; + } + r[t] = i + dict[t]; + } + foreach (T t in other.dict.Keys) { + var i = 0; + if (!r.TryGetValue(t, out i)) { + i = 0; + } + r[t] = i + other.dict[t]; + } + return new MultiSet(r); + } + public MultiSet Intersect(MultiSet other) { + if (dict.Count == 0) + return this; + else if (other.dict.Count == 0) + return other; + var r = new Dictionary(); + foreach (T t in dict.Keys) { + if (other.dict.ContainsKey(t)) { + r.Add(t, other.dict[t] < dict[t] ? other.dict[t] : dict[t]); + } + } + return new MultiSet(r); + } + public MultiSet Difference(MultiSet other) { // \result == this - other + if (dict.Count == 0) + return this; + else if (other.dict.Count == 0) + return this; + var r = new Dictionary(); + foreach (T t in dict.Keys) { + if (!other.dict.ContainsKey(t)) { + r.Add(t, dict[t]); + } else if (other.dict[t] < dict[t]) { + r.Add(t, dict[t] - other.dict[t]); + } + } + return new MultiSet(r); + } + public IEnumerable Elements { + get { + List l = new List(); + foreach (T t in dict.Keys) { + int n; + dict.TryGetValue(t, out n); + for (int i = 0; i < n; i ++) { + l.Add(t); + } + } + return l; + } + } + } + + public class Map + { + Dictionary dict; + public Map() { } + Map(Dictionary d) { + dict = d; + } + public static Map Empty { + get { + return new Map(new Dictionary()); + } + } + public static Map FromElements(params Pair[] values) { + Dictionary d = new Dictionary(values.Length); + foreach (Pair p in values) { + d[p.Car] = p.Cdr; + } + return new Map(d); + } + public static Map FromCollection(List> values) { + Dictionary d = new Dictionary(values.Count); + foreach (Pair p in values) { + d[p.Car] = p.Cdr; + } + return new Map(d); + } + public bool Equals(Map other) { + foreach (U u in dict.Keys) { + V v1, v2; + if (!dict.TryGetValue(u, out v1)) { + return false; // this shouldn't happen + } + if (!other.dict.TryGetValue(u, out v2)) { + return false; // other dictionary does not contain this element + } + if (!v1.Equals(v2)) { + return false; + } + } + foreach (U u in other.dict.Keys) { + if (!dict.ContainsKey(u)) { + return false; // this shouldn't happen + } + } + return true; + } + public override bool Equals(object other) { + return other is Map && Equals((Map)other); + } + public override int GetHashCode() { + return dict.GetHashCode(); + } + public bool IsDisjointFrom(Map other) { + foreach (U u in dict.Keys) { + if (other.dict.ContainsKey(u)) + return false; + } + foreach (U u in other.dict.Keys) { + if (dict.ContainsKey(u)) + return false; + } + return true; + } + public bool Contains(U u) { + return dict.ContainsKey(u); + } + public V Select(U index) { + return dict[index]; + } + public Map Update(U index, V val) { + Dictionary d = new Dictionary(dict); + d[index] = val; + return new Map(d); + } + public IEnumerable Domain { + get { + return dict.Keys; + } + } + } + public class Sequence + { + T[] elmts; + public Sequence() { } + public 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 IEnumerable UniqueElements { + get { + var st = Set.FromElements(elmts); + return st.Elements; + } + } + 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 { + // Computing forall/exists quantifiers + 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 u in set.Elements) { + if (pred(u) != frall) { return !frall; } + } + return frall; + } + public static bool QuantMap(Dafny.Map map, bool frall, System.Predicate pred) { + foreach (var u in map.Domain) { + if (pred(u) != frall) { return !frall; } + } + return frall; + } + public static bool QuantSeq(Dafny.Sequence seq, bool frall, System.Predicate pred) { + foreach (var u in seq.Elements) { + if (pred(u) != frall) { return !frall; } + } + return frall; + } + public static bool QuantDatatype(IEnumerable set, bool frall, System.Predicate pred) { + foreach (var u in set) { + if (pred(u) != frall) { return !frall; } + } + return frall; + } + // Enumerating other collections + public delegate Dafny.Set ComprehensionDelegate(); + public delegate Dafny.Map MapComprehensionDelegate(); + public static IEnumerable AllBooleans { + get { + yield return false; + yield return true; + } + } + // pre: b != 0 + // post: result == a/b, as defined by Euclidean Division (http://en.wikipedia.org/wiki/Modulo_operation) + public static BigInteger EuclideanDivision(BigInteger a, BigInteger b) { + if (0 <= a.Sign) { + if (0 <= b.Sign) { + // +a +b: a/b + return BigInteger.Divide(a, b); + } else { + // +a -b: -(a/(-b)) + return BigInteger.Negate(BigInteger.Divide(a, BigInteger.Negate(b))); + } + } else { + if (0 <= b.Sign) { + // -a +b: -((-a-1)/b) - 1 + return BigInteger.Negate(BigInteger.Divide(BigInteger.Negate(a) - 1, b)) - 1; + } else { + // -a -b: ((-a-1)/(-b)) + 1 + return BigInteger.Divide(BigInteger.Negate(a) - 1, BigInteger.Negate(b)) + 1; + } + } + } + // pre: b != 0 + // post: result == a%b, as defined by Euclidean Division (http://en.wikipedia.org/wiki/Modulo_operation) + public static BigInteger EuclideanModulus(BigInteger a, BigInteger b) { + var bp = BigInteger.Abs(b); + if (0 <= a.Sign) { + // +a: a % b' + return BigInteger.Remainder(a, bp); + } else { + // c = ((-a) % b') + // -a: b' - c if c > 0 + // -a: 0 if c == 0 + var c = BigInteger.Remainder(BigInteger.Negate(a), bp); + return c.IsZero ? c : BigInteger.Subtract(bp, c); + } + } + public static Sequence SeqFromArray(T[] array) { + return new Sequence(array); + } + // In .NET version 4.5, it it possible to mark a method with "AggressiveInlining", which says to inline the + // method if possible. Method "ExpressionSequence" would be a good candidate for it: + // [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static U ExpressionSequence(T t, U u) + { + return u; + } + } +} -- cgit v1.2.3