Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
//
// AbstractDomainExtensions.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2012 Alexander Chebaturkin
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using Mono.CodeContracts.Static.DataStructures;
namespace Mono.CodeContracts.Static.Lattices {
public static class AbstractDomainExtensions {
public static bool IsNormal<T> (this IAbstractDomain<T> domain)
{
return !domain.IsTop && !domain.IsBottom;
}
public static string BottomSymbolIfAny<T> (this IAbstractDomain<T> domain)
{
return domain.IsBottom ? "_|_" : string.Empty;
}
public static bool TryTrivialLessEqual<T> (this T left, T right, out bool result)
where T : IAbstractDomain<T>
{
if (ReferenceEquals (left, right))
return true.With (true, out result);
if (left.IsBottom)
return true.With (true, out result);
if (left.IsTop)
return true.With (right.IsTop, out result);
if (right.IsBottom)
return true.With (false, out result);
if (right.IsTop)
return true.With (true, out result);
return false.Without (out result);
}
public static bool TryTrivialJoin<T> (this T left, T right, out T result)
where T : IAbstractDomain<T>
{
if (ReferenceEquals (left, right))
return true.With (left, out result);
if (left.IsBottom)
return true.With (right, out result);
if (left.IsTop)
return true.With (left, out result);
if (right.IsBottom)
return true.With (left, out result);
if (right.IsTop)
return true.With (right, out result);
return false.Without (out result);
}
public static bool TryTrivialMeet<T> (this T left, T right, out T result)
where T : IAbstractDomain<T>
{
if (ReferenceEquals (left, right))
return true.With (left, out result);
if (left.IsBottom)
return true.With (left, out result);
if (left.IsTop)
return true.With (right, out result);
if (right.IsBottom)
return true.With (right, out result);
if (right.IsTop)
return true.With (left, out result);
return false.Without (out result);
}
}
}

View File

@@ -0,0 +1,297 @@
//
// EnvironmentDomain.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2011 Alexander Chebaturkin
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Mono.CodeContracts.Static.DataStructures;
namespace Mono.CodeContracts.Static.Lattices {
class EnvironmentDomain<K, V> : IAbstractDomain<EnvironmentDomain<K, V>>
where V : IAbstractDomain<V>
where K : IEquatable<K> {
readonly IImmutableMapFactory<K, V> factory;
readonly IImmutableMap<K, V> map;
EnvironmentDomain (IImmutableMapFactory<K, V> factory)
: this (factory, factory.Empty)
{
}
EnvironmentDomain (IImmutableMap<K, V> map)
: this (map.Factory (), map)
{
}
EnvironmentDomain (IImmutableMapFactory<K, V> factory, IImmutableMap<K, V> map)
{
this.factory = factory;
this.map = map;
}
public V this [K key] { get { return map == null ? default(V) : map[key]; } }
public IEnumerable<K> Keys { get { return map.Keys; } }
#region IAbstractDomain<EnvironmentDomain<K,V>> Members
public EnvironmentDomain<K, V> Top { get { return new EnvironmentDomain<K, V> (factory.Empty); } }
public EnvironmentDomain<K, V> Bottom { get { return new EnvironmentDomain<K, V> (factory, null); } }
public bool IsTop { get { return map != null && map.Count == 0; } }
public bool IsBottom { get { return map == null; } }
public EnvironmentDomain<K, V> Join (EnvironmentDomain<K, V> that)
{
return JoinOrWiden (that, (a, b) => a.Join (b));
}
public EnvironmentDomain<K, V> Widen (EnvironmentDomain<K, V> that)
{
return JoinOrWiden (that, (a, b) => a.Widen (b));
}
EnvironmentDomain<K, V> JoinOrWiden (EnvironmentDomain<K, V> that, Func<V, V, V> op)
{
if (ReferenceEquals (map, that.map) || IsBottom)
return that;
if (that.IsBottom)
return this;
IImmutableMap<K, V> min;
IImmutableMap<K, V> max;
GetMinAndMaxByCount (map, that.map, out min, out max);
var result = min; // intersection of keys
foreach (var key in min.Keys) {
V thatValue;
if (max.TryGetValue (key, out thatValue)) {
var join = op (min[key], thatValue);
if (join.IsBottom)
return Bottom;
result = join.IsTop ? result.Remove (key) : result.Add (key, join);
}
else
result = result.Remove (key);
}
return new EnvironmentDomain<K, V> (result);
}
public EnvironmentDomain<K, V> Join (EnvironmentDomain<K, V> that, bool widening, out bool weaker)
{
//todo: remove it
weaker = false;
if (map == that.map || IsTop)
return this;
if (that.IsTop) {
weaker = !IsTop;
return that;
}
if (IsBottom) {
weaker = !that.IsBottom;
return that;
}
if (that.IsBottom)
return this;
IImmutableMap<K, V> min;
IImmutableMap<K, V> max;
GetMinAndMaxByCount (map, that.map, out min, out max);
var intersect = min;
foreach (var key in min.Keys) {
if (!max.ContainsKey (key))
intersect = intersect.Remove (key);
else {
bool keyWeaker;
var join = min[key].Join (max[key], widening, out keyWeaker);
if (keyWeaker) {
weaker = true;
intersect = join.IsTop ? intersect.Remove (key) : intersect.Add (key, join);
}
}
}
weaker |= intersect.Count < map.Count;
return new EnvironmentDomain<K, V> (intersect);
}
public EnvironmentDomain<K, V> Meet (EnvironmentDomain<K, V> that)
{
if (ReferenceEquals (map, that.map))
return this;
if (IsTop)
return that;
if (that.IsTop || IsBottom)
return this;
if (that.IsBottom)
return that;
IImmutableMap<K, V> min;
IImmutableMap<K, V> max;
GetMinAndMaxByCount (map, that.map, out min, out max);
var union = max;
foreach (var key in min.Keys) {
if (!max.ContainsKey (key))
union = union.Add (key, min[key]);
else {
var meet = min[key].Meet (max[key]);
union = union.Add (key, meet);
}
}
return new EnvironmentDomain<K, V> (union);
}
public bool LessEqual (EnvironmentDomain<K, V> that)
{
bool result;
if (this.TryTrivialLessEqual (that, out result))
return result;
if (map.Count < that.map.Count)
return false;
return that.map.Keys.All (key => map.ContainsKey (key) && map[key].LessEqual (that.map[key]));
}
public EnvironmentDomain<K, V> ImmutableVersion ()
{
return this;
}
public EnvironmentDomain<K, V> Clone ()
{
return this;
}
public void Dump (TextWriter tw)
{
if (IsTop)
tw.WriteLine ("Top");
else if (IsBottom)
tw.WriteLine (this.BottomSymbolIfAny ());
else {
map.Visit ((k, v) => {
tw.WriteLine ("{0} -> {1}", k, v);
return VisitStatus.ContinueVisit;
});
}
}
#endregion
public static EnvironmentDomain<K, V> TopValue (Func<K, int> keyConverter)
{
if (keyConverter == null)
throw new ArgumentNullException ("keyConverter");
return new EnvironmentDomain<K, V> (ImmutableIntKeyMap<K, V>.Empty (keyConverter));
}
public static EnvironmentDomain<K, V> TopValue ()
{
return new EnvironmentDomain<K, V> (ImmutableMap<K, V>.Empty);
}
public static EnvironmentDomain<K, V> BottomValue (Func<K, int> keyConverter)
{
if (keyConverter == null)
throw new ArgumentNullException ("keyConverter");
return new EnvironmentDomain<K, V> (ImmutableIntKeyMap<K, V>.Empty (keyConverter).Factory (), null);
}
public static EnvironmentDomain<K, V> BottomValue ()
{
return new EnvironmentDomain<K, V> (ImmutableMap<K, V>.Empty.Factory (), null);
}
public EnvironmentDomain<K, V> With (K key, V value)
{
if (value.IsTop)
return Without (key);
return new EnvironmentDomain<K, V> (map.Add (key, value));
}
public EnvironmentDomain<K, V> RefineWith (K key, V value)
{
V old;
if (map.TryGetValue (key, out old))
value = value.Meet (old);
return With (key, value);
}
public EnvironmentDomain<K, V> Without (K key)
{
return new EnvironmentDomain<K, V> (map.Remove (key));
}
public bool Contains (K key)
{
return map != null && map.ContainsKey (key);
}
public bool TryGetValue (K key, out V value)
{
if (map == null)
return false.Without (out value);
return map.TryGetValue (key, out value);
}
public EnvironmentDomain<K, V> Empty ()
{
return new EnvironmentDomain<K, V> (factory.Empty);
}
static bool GetMinAndMaxByCount
(IImmutableMap<K, V> a, IImmutableMap<K, V> b,
out IImmutableMap<K, V> min, out IImmutableMap<K, V> max)
{
if (a.Count < b.Count) {
min = a;
max = b;
return true;
}
max = a;
min = b;
return false;
}
}
}

View File

@@ -0,0 +1,183 @@
//
// FlatDomain.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2011 Alexander Chebaturkin
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.IO;
namespace Mono.CodeContracts.Static.Lattices {
/// <summary>
/// Represents domain, where abstract values are disjunct, and their join/meet turns into Top/Bottom respectively
/// </summary>
/// <example>
/// Top
/// / | \
/// v1 v2 v3
/// \ | /
/// Bot
/// </example>
/// <typeparam name="T"></typeparam>
public struct FlatDomain<T> : IAbstractDomain<FlatDomain<T>>, IEquatable<FlatDomain<T>>
where T : IEquatable<T> {
public static readonly FlatDomain<T> BottomValue = new FlatDomain<T> (DomainKind.Bottom);
public static readonly FlatDomain<T> TopValue = new FlatDomain<T> (DomainKind.Top);
public readonly T Value;
readonly DomainKind state;
FlatDomain (DomainKind state)
{
this.state = state;
Value = default(T);
}
public FlatDomain (T value)
{
state = DomainKind.Normal;
Value = value;
}
public static implicit operator FlatDomain<T> (T value)
{
return new FlatDomain<T> (value);
}
#region Implementation of IAbstractDomain<FlatDomain<T>>
public FlatDomain<T> Top { get { return TopValue; } }
public FlatDomain<T> Bottom { get { return BottomValue; } }
public bool IsTop { get { return state == DomainKind.Top; } }
public bool IsBottom { get { return state == DomainKind.Bottom; } }
public FlatDomain<T> Join (FlatDomain<T> that, bool widening, out bool weaker)
{
if (IsTop || that.IsBottom) {
weaker = false;
return this;
}
if (that.IsTop) {
weaker = !IsTop;
return that;
}
if (IsBottom) {
weaker = !that.IsBottom;
return that;
}
if (Value.Equals (that.Value)) {
weaker = false;
return that;
}
weaker = true;
return TopValue;
}
public FlatDomain<T> Widen (FlatDomain<T> that)
{
// no widening - it's finite lattice
return Join (that);
}
public FlatDomain<T> Join (FlatDomain<T> that)
{
FlatDomain<T> result;
if (this.TryTrivialJoin (that, out result))
return result;
// this and that must be normal here
return Value.Equals (that.Value) ? this : TopValue;
}
public FlatDomain<T> Meet (FlatDomain<T> that)
{
FlatDomain<T> result;
if (this.TryTrivialMeet (that, out result))
return result;
return Value.Equals (that.Value) ? this : BottomValue;
}
public bool LessEqual (FlatDomain<T> that)
{
bool result;
if (this.TryTrivialLessEqual (that, out result))
return result;
return Value.Equals (that.Value);
}
public FlatDomain<T> ImmutableVersion ()
{
return this;
}
public FlatDomain<T> Clone ()
{
return this;
}
public void Dump (TextWriter tw)
{
if (IsTop)
tw.WriteLine ("Top");
else if (IsBottom)
tw.WriteLine (this.BottomSymbolIfAny ());
else
tw.WriteLine ("<{0}>", Value);
}
public override string ToString ()
{
if (IsTop)
return "Top";
if (IsBottom)
return this.BottomSymbolIfAny ();
return string.Format ("<{0}>", Value);
}
#endregion
public bool Equals (FlatDomain<T> that)
{
if (!this.IsNormal ())
return state == that.state;
return that.IsNormal () && Value.Equals (that.Value);
}
}
enum DomainKind {
Normal = 0,
Top,
Bottom
}
}

View File

@@ -0,0 +1,82 @@
//
// IAbstractDomain.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2011 Alexander Chebaturkin
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.IO;
namespace Mono.CodeContracts.Static.Lattices {
/// <summary>
/// Represents abstraction of concrete value
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IAbstractDomain<T> {
/// <summary>
/// Represents universe set (which holds every value)
/// </summary>
T Top { get; }
/// <summary>
/// Represents empty set (which holds nothing)
/// </summary>
T Bottom { get; }
/// <summary>
/// Is this value a universe set
/// </summary>
bool IsTop { get; }
/// <summary>
/// Is this value an empty set
/// </summary>
bool IsBottom { get; }
/// <summary>
/// Returns a union of this and that
/// </summary>
/// <param name="that"></param>
/// <returns></returns>
T Join (T that);
T Join (T that, bool widen, out bool weaker);
T Widen (T that);
/// <summary>
/// Returns an intersection of this and that
/// </summary>
/// <param name="that"></param>
/// <returns></returns>
T Meet (T that);
bool LessEqual (T that);
T ImmutableVersion ();
T Clone ();
void Dump (TextWriter tw);
}
}

View File

@@ -0,0 +1,155 @@
//
// SetDomain.cs
//
// Authors:
// Alexander Chebaturkin (chebaturkin@gmail.com)
//
// Copyright (C) 2011 Alexander Chebaturkin
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.IO;
using Mono.CodeContracts.Static.DataStructures;
namespace Mono.CodeContracts.Static.Lattices {
struct SetDomain<T> : IAbstractDomain<SetDomain<T>>
where T : IEquatable<T> {
public static readonly SetDomain<T> TopValue = new SetDomain<T> (ImmutableSet<T>.Empty ());
public static readonly SetDomain<T> BottomValue = new SetDomain<T> ((IImmutableSet<T>) null);
readonly IImmutableSet<T> set;
SetDomain (IImmutableSet<T> set)
{
this.set = set;
}
public SetDomain (Func<T, int> keyConverter)
{
set = ImmutableSet<T>.Empty (keyConverter);
}
public SetDomain<T> Top { get { return TopValue; } }
public SetDomain<T> Bottom { get { return BottomValue; } }
public bool IsTop { get { return set != null && set.Count == 0; } }
public bool IsBottom { get { return set == null; } }
public SetDomain<T> Join (SetDomain<T> that)
{
SetDomain<T> result;
if (this.TryTrivialJoin (that, out result))
return result;
return new SetDomain<T> (set.Intersect (that.set));
}
public SetDomain<T> Join (SetDomain<T> that, bool widening, out bool weaker)
{
if (set == that.set) {
weaker = false;
return this;
}
if (IsBottom) {
weaker = !that.IsBottom;
return that;
}
if (that.IsBottom || IsTop) {
weaker = false;
return this;
}
if (that.IsTop) {
weaker = !IsTop;
return that;
}
var join = set.Intersect (that.set);
weaker = join.Count < set.Count;
return new SetDomain<T> (join);
}
public SetDomain<T> Widen (SetDomain<T> that)
{
//no widening - finite lattice
return Join (that);
}
public SetDomain<T> Meet (SetDomain<T> that)
{
SetDomain<T> result;
if (this.TryTrivialMeet (that, out result))
return result;
return new SetDomain<T> (set.Union (that.set));
}
public bool LessEqual (SetDomain<T> that)
{
if (IsBottom)
return true;
if (that.IsBottom)
return false;
return that.set.IsContainedIn (set);
}
public SetDomain<T> ImmutableVersion ()
{
return this;
}
public SetDomain<T> Clone ()
{
return this;
}
public SetDomain<T> With (T elem)
{
return new SetDomain<T> (set.Add (elem));
}
public SetDomain<T> Without (T elem)
{
return new SetDomain<T> (set.Remove (elem));
}
public bool Contains (T item)
{
return set.Contains (item);
}
public void Dump (TextWriter tw)
{
if (IsBottom)
tw.WriteLine ("Bot");
else if (IsTop)
tw.WriteLine ("Top");
else
set.Dump (tw);
}
}
}