From a297fb4b9e6c0b915b5bb5bd85050b26a9ed7e3b Mon Sep 17 00:00:00 2001 From: Michael Lowell Roberts Date: Fri, 12 Jun 2015 11:12:35 -0700 Subject: added -optimize option to compiler. --- Binaries/DafnyRuntime.cs | 506 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 449 insertions(+), 57 deletions(-) (limited to 'Binaries') diff --git a/Binaries/DafnyRuntime.cs b/Binaries/DafnyRuntime.cs index fd680a0b..7d3799d8 100644 --- a/Binaries/DafnyRuntime.cs +++ b/Binaries/DafnyRuntime.cs @@ -4,39 +4,430 @@ using System.Numerics; namespace Dafny { using System.Collections.Generic; +// set this option if you want to use System.Collections.Immutable and if you know what you're doing. +#if DAFNY_USE_SYSTEM_COLLECTIONS_IMMUTABLE + using System.Collections.Immutable; + using System.Linq; public class Set { - Dictionary dict; - Set(Dictionary d) { + readonly ImmutableHashSet setImpl; + Set(ImmutableHashSet d) { + this.setImpl = d; + } + public static readonly Set Empty = new Set(ImmutableHashSet.Empty); + public static Set FromElements(params T[] values) { + return FromElements((IEnumerable)values); + } + public static Set FromElements(IEnumerable values) { + var d = ImmutableHashSet.Empty.ToBuilder(); + foreach (T t in values) + d.Add(t); + return new Set(d.ToImmutable()); + } + public static Set FromCollection(ICollection values) { + var d = ImmutableHashSet.Empty.ToBuilder(); + foreach (T t in values) + d.Add(t); + return new Set(d.ToImmutable()); + } + public int Length { + get { return this.setImpl.Count; } + } + public long LongLength { + get { return this.setImpl.Count; } + } + public IEnumerable Elements { + get { + return this.setImpl; + } + } + /// + /// This is an inefficient iterator for producing all subsets of "this". Each set returned is the same + /// Set object (but this Set object is fresh; in particular, it is not "this"). + /// + public IEnumerable> AllSubsets { + get { + // Start by putting all set elements into a list + var elmts = new List(); + elmts.AddRange(this.setImpl); + var n = elmts.Count; + var which = new bool[n]; + var s = ImmutableHashSet.Empty.ToBuilder(); + while (true) { + yield return new Set(s.ToImmutable()); + // "add 1" to "which", as if doing a carry chain. For every digit changed, change the membership of the corresponding element in "s". + int i = 0; + for (; i < n && which[i]; i++) { + which[i] = false; + s.Remove(elmts[i]); + } + if (i == n) { + // we have cycled through all the subsets + break; + } + which[i] = true; + s.Add(elmts[i]); + } + } + } + public bool Equals(Set other) { + return this.setImpl.Equals(other.setImpl); + } + public override bool Equals(object other) { + var otherSet = other as Set; + return otherSet != null && Equals(otherSet); + } + public override int GetHashCode() { + var hashCode = 1; + foreach (var t in this.setImpl) { + hashCode = hashCode * (t.GetHashCode()+3); + } + return hashCode; + } + public override string ToString() { + var s = "{"; + var sep = ""; + foreach (var t in this.setImpl) { + s += sep + t.ToString(); + sep = ", "; + } + return s + "}"; + } + public bool IsProperSubsetOf(Set other) { + return IsProperSubsetOf(other); + } + public bool IsSubsetOf(Set other) { + return IsSubsetOf(other); + } + public bool IsSupersetOf(Set other) { + return other.IsSupersetOf(this); + } + public bool IsProperSupersetOf(Set other) { + return other.IsProperSupersetOf(this); + } + public bool IsDisjointFrom(Set other) { + ImmutableHashSet a, b; + if (this.setImpl.Count < other.setImpl.Count) { + a = this.setImpl; b = other.setImpl; + } else { + a = other.setImpl; b = this.setImpl; + } + foreach (T t in a) { + if (b.Contains(t)) + return false; + } + return true; + } + public bool Contains(T t) { + return this.setImpl.Contains(t); + } + public Set Union(Set other) { + return new Set(this.setImpl.Union(other.setImpl)); + } + public Set Intersect(Set other) { + return new Set(this.setImpl.Intersect(other.setImpl)); + } + public Set Difference(Set other) { + return new Set(this.setImpl.Except(other.setImpl)); + } + } + public partial class MultiSet + { + + readonly ImmutableDictionary dict; + MultiSet(ImmutableDictionary d) { dict = d; } + public static readonly MultiSet Empty = new MultiSet(ImmutableDictionary.Empty); + public static MultiSet FromElements(params T[] values) { + var d = ImmutableDictionary.Empty.ToBuilder(); + foreach (T t in values) { + var i = 0; + if (!d.TryGetValue(t, out i)) { + i = 0; + } + d[t] = i + 1; + } + return new MultiSet(d.ToImmutable()); + } + public static MultiSet FromCollection(ICollection values) { + var d = ImmutableDictionary.Empty.ToBuilder(); + foreach (T t in values) { + var i = 0; + if (!d.TryGetValue(t, out i)) { + i = 0; + } + d[t] = i + 1; + } + return new MultiSet(d.ToImmutable()); + } + public static MultiSet FromSeq(Sequence values) { + var d = ImmutableDictionary.Empty.ToBuilder(); + 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.ToImmutable()); + } + public static MultiSet FromSet(Set values) { + var d = ImmutableDictionary.Empty.ToBuilder(); + foreach (T t in values.Elements) { + d[t] = 1; + } + return new MultiSet(d.ToImmutable()); + } + + 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() { + var hashCode = 1; + foreach (var kv in dict) { + var key = kv.Key.GetHashCode(); + key = (key << 3) | (key >> 29) ^ kv.Value.GetHashCode(); + hashCode = hashCode * (key + 3); + } + return hashCode; + } + public override string ToString() { + var s = "multiset{"; + var sep = ""; + foreach (var kv in dict) { + var t = kv.Key.ToString(); + for (int i = 0; i < kv.Value; i++) { + s += sep + t.ToString(); + sep = ", "; + } + } + return s + "}"; + } + 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 = ImmutableDictionary.Empty.ToBuilder(); + 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.ToImmutable()); + } + public MultiSet Intersect(MultiSet other) { + if (dict.Count == 0) + return this; + else if (other.dict.Count == 0) + return other; + var r = ImmutableDictionary.Empty.ToBuilder(); + foreach (T t in dict.Keys) { + if (other.dict.ContainsKey(t)) { + r[t] = other.dict[t] < dict[t] ? other.dict[t] : dict[t]; + } + } + return new MultiSet(r.ToImmutable()); + } + public MultiSet Difference(MultiSet other) { // \result == this - other + if (dict.Count == 0) + return this; + else if (other.dict.Count == 0) + return this; + var r = ImmutableDictionary.Empty.ToBuilder(); + foreach (T t in dict.Keys) { + if (!other.dict.ContainsKey(t)) { + r[t] = dict[t]; + } else if (other.dict[t] < dict[t]) { + r[t] = dict[t] - other.dict[t]; + } + } + return new MultiSet(r.ToImmutable()); + } + public IEnumerable Elements { + get { + foreach (T t in dict.Keys) { + int n; + dict.TryGetValue(t, out n); + for (int i = 0; i < n; i ++) { + yield return t; + } + } + } + } + } + + public partial class Map + { + readonly ImmutableDictionary dict; + Map(ImmutableDictionary d) { + dict = d; + } + public static readonly Map Empty = new Map(ImmutableDictionary.Empty); + public static Map FromElements(params Pair[] values) { + var d = ImmutableDictionary.Empty.ToBuilder(); + foreach (Pair p in values) { + d[p.Car] = p.Cdr; + } + return new Map(d.ToImmutable()); + } + public static Map FromCollection(List> values) { + var d = ImmutableDictionary.Empty.ToBuilder(); + foreach (Pair p in values) { + d[p.Car] = p.Cdr; + } + return new Map(d.ToImmutable()); + } + public int Length { + get { return dict.Count; } + } + public long LongLength { + get { return dict.Count; } + } + 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() { + var hashCode = 1; + foreach (var kv in dict) { + var key = kv.Key.GetHashCode(); + key = (key << 3) | (key >> 29) ^ kv.Value.GetHashCode(); + hashCode = hashCode * (key + 3); + } + return hashCode; + } + public override string ToString() { + var s = "map["; + var sep = ""; + foreach (var kv in dict) { + s += sep + kv.Key.ToString() + " := " + kv.Value.ToString(); + sep = ", "; + } + return s + "]"; + } + 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) { + return new Map(dict.SetItem(index, val)); + } + public IEnumerable Domain { + get { + return dict.Keys; + } + } + } +#else // !def DAFNY_USE_SYSTEM_COLLECTIONS_IMMUTABLE + public class Set + { + HashSet set; + Set(HashSet s) { + this.set = s; + } public static Set Empty { get { - return new Set(new Dictionary(0)); + return new Set(new HashSet()); } } public static Set FromElements(params T[] values) { - Dictionary d = new Dictionary(values.Length); + var s = new HashSet(); foreach (T t in values) - d[t] = true; - return new Set(d); + s.Add(t); + return new Set(s); } public static Set FromCollection(ICollection values) { - Dictionary d = new Dictionary(); + HashSet s = new HashSet(); foreach (T t in values) - d[t] = true; - return new Set(d); + s.Add(t); + return new Set(s); } public int Length { - get { return dict.Count; } + get { return this.set.Count; } } public long LongLength { - get { return dict.Count; } + get { return this.set.Count; } } public IEnumerable Elements { get { - return dict.Keys; + return this.set; } } /// @@ -47,36 +438,36 @@ namespace Dafny get { // Start by putting all set elements into a list var elmts = new List(); - elmts.AddRange(dict.Keys); + elmts.AddRange(this.set); var n = elmts.Count; var which = new bool[n]; - var s = new Set(new Dictionary(0)); + var s = new Set(new HashSet()); while (true) { yield return s; // "add 1" to "which", as if doing a carry chain. For every digit changed, change the membership of the corresponding element in "s". int i = 0; for (; i < n && which[i]; i++) { which[i] = false; - s.dict.Remove(elmts[i]); + s.set.Remove(elmts[i]); } if (i == n) { // we have cycled through all the subsets break; } which[i] = true; - s.dict.Add(elmts[i], true); + s.set.Add(elmts[i]); } } } public bool Equals(Set other) { - return dict.Count == other.dict.Count && IsSubsetOf(other); + return this.set.Count == other.set.Count && IsSubsetOf(other); } public override bool Equals(object other) { return other is Set && Equals((Set)other); } public override int GetHashCode() { var hashCode = 1; - foreach (var t in dict.Keys) { + foreach (var t in this.set) { hashCode = hashCode * (t.GetHashCode()+3); } return hashCode; @@ -84,20 +475,20 @@ namespace Dafny public override string ToString() { var s = "{"; var sep = ""; - foreach (var t in dict.Keys) { + foreach (var t in this.set) { s += sep + t.ToString(); sep = ", "; } return s + "}"; } public bool IsProperSubsetOf(Set other) { - return dict.Count < other.dict.Count && IsSubsetOf(other); + return this.set.Count < other.set.Count && IsSubsetOf(other); } public bool IsSubsetOf(Set other) { - if (other.dict.Count < dict.Count) + if (other.set.Count < this.set.Count) return false; - foreach (T t in dict.Keys) { - if (!other.dict.ContainsKey(t)) + foreach (T t in this.set) { + if (!other.set.Contains(t)) return false; } return true; @@ -109,66 +500,66 @@ namespace Dafny return other.IsProperSubsetOf(this); } public bool IsDisjointFrom(Set other) { - Dictionary a, b; - if (dict.Count < other.dict.Count) { - a = dict; b = other.dict; + HashSet a, b; + if (this.set.Count < other.set.Count) { + a = this.set; b = other.set; } else { - a = other.dict; b = dict; + a = other.set; b = this.set; } - foreach (T t in a.Keys) { - if (b.ContainsKey(t)) + foreach (T t in a) { + if (b.Contains(t)) return false; } return true; } public bool Contains(T t) { - return dict.ContainsKey(t); + return this.set.Contains(t); } public Set Union(Set other) { - if (dict.Count == 0) + if (this.set.Count == 0) return other; - else if (other.dict.Count == 0) + else if (other.set.Count == 0) return this; - Dictionary a, b; - if (dict.Count < other.dict.Count) { - a = dict; b = other.dict; + HashSet a, b; + if (this.set.Count < other.set.Count) { + a = this.set; b = other.set; } else { - a = other.dict; b = dict; + a = other.set; b = this.set; } - Dictionary r = new Dictionary(); - foreach (T t in b.Keys) - r[t] = true; - foreach (T t in a.Keys) - r[t] = true; + var r = new HashSet(); + foreach (T t in b) + r.Add(t); + foreach (T t in a) + r.Add(t); return new Set(r); } public Set Intersect(Set other) { - if (dict.Count == 0) + if (this.set.Count == 0) return this; - else if (other.dict.Count == 0) + else if (other.set.Count == 0) return other; - Dictionary a, b; - if (dict.Count < other.dict.Count) { - a = dict; b = other.dict; + HashSet a, b; + if (this.set.Count < other.set.Count) { + a = this.set; b = other.set; } else { - a = other.dict; b = dict; + a = other.set; b = this.set; } - var r = new Dictionary(); - foreach (T t in a.Keys) { - if (b.ContainsKey(t)) - r.Add(t, true); + var r = new HashSet(); + foreach (T t in a) { + if (b.Contains(t)) + r.Add(t); } return new Set(r); } public Set Difference(Set other) { - if (dict.Count == 0) + if (this.set.Count == 0) return this; - else if (other.dict.Count == 0) + else if (other.set.Count == 0) return this; - var r = new Dictionary(); - foreach (T t in dict.Keys) { - if (!other.dict.ContainsKey(t)) - r.Add(t, true); + var r = new HashSet(); + foreach (T t in this.set) { + if (!other.set.Contains(t)) + r.Add(t); } return new Set(r); } @@ -447,6 +838,7 @@ namespace Dafny } } } +#endif public class Sequence { T[] elmts; -- cgit v1.2.3