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,75 @@
//
// AbstractWorkList.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.Collections.Generic;
namespace Mono.CodeContracts.Static.DataStructures {
abstract class AbstractWorkList<T> : IWorkList<T> {
protected HashSet<T> Elements = new HashSet<T> ();
protected abstract IEnumerable<T> Collection { get; }
public int Count
{
get { return this.Elements.Count; }
}
protected abstract void AddToCollection (T o);
#region Implementation of IWorkList<T>
public virtual bool Add (T o)
{
if (!this.Elements.Add (o))
return false;
AddToCollection (o);
return true;
}
public virtual bool IsEmpty ()
{
return this.Elements.Count == 0;
}
public abstract T Pull ();
public virtual bool AddAll (IEnumerable<T> objs)
{
bool any = false;
foreach (T o in objs) {
if (Add (o))
any = true;
}
return any;
}
public virtual IEnumerator<T> GetEnumerator ()
{
return Collection.GetEnumerator ();
}
#endregion
}
}

View File

@@ -0,0 +1,63 @@
//
// BooleanExtensions.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.Lattices;
namespace Mono.CodeContracts.Static.DataStructures
{
static class BooleanExtensions
{
/// <summary>
/// Returns value and sets result to a resultValue.
/// </summary>
public static bool With<T>(this bool value, T resultValue, out T result)
{
result = resultValue;
return value;
}
/// <summary>
/// Returns value and sets result to a default(T).
/// </summary>
public static bool Without<T>(this bool value, out T result)
{
result = default(T);
return value;
}
/// <summary>
/// Returns ProofOutcome value based on input.
/// </summary>
/// <param name="condition">Condition to check.</param>
/// <returns><see cref="ProofOutcome.True"/> if condition holds, otherwise <see cref="ProofOutcome.Top"/></returns>
public static FlatDomain<bool> ToTrueOrTop(this bool condition)
{
return condition ? ProofOutcome.True : ProofOutcome.Top;
}
}
}

View File

@@ -0,0 +1,95 @@
//
// DecoratorHelper.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 System;
using System.Collections.Generic;
namespace Mono.CodeContracts.Static.DataStructures {
/// <summary>
/// This class is used with subroutines to substitute IStackInfo and IEdgeSubroutineAdapter to desired
/// </summary>
static class DecoratorHelper {
private static readonly List<object> ContextAdapters = new List<object> ();
private static object Last
{
get { return ContextAdapters [ContextAdapters.Count - 1]; }
}
public static void Push<T> (T @this) where T : class
{
ContextAdapters.Add (@this);
}
public static void Pop ()
{
ContextAdapters.RemoveAt (ContextAdapters.Count - 1);
}
public static T Dispatch<T> (T @this) where T : class
{
return FindAdaptorStartingAt (@this, 0);
}
private static T FindAdaptorStartingAt<T> (T @default, int startIndex)
where T : class
{
List<object> list = ContextAdapters;
for (int i = startIndex; i < list.Count; ++i) {
var obj = list [i] as T;
if (obj != null)
return obj;
}
return @default;
}
public static T Inner<T> (T @this) where T : class
{
for (int i = 0; i < ContextAdapters.Count; i++) {
if (ContextAdapters [i] == @this) {
ClearDuplicates (@this, i + 1);
T inner = FindAdaptorStartingAt (default(T), i + 1);
if (inner != null)
return inner;
throw new InvalidOperationException ("No inner context found");
}
}
throw new InvalidOperationException ("@this is not current adaptor");
}
private static void ClearDuplicates (object @this, int @from)
{
for (int i = from; i < ContextAdapters.Count; i++) {
if (ContextAdapters [i] == @this)
ContextAdapters [i] = null;
}
}
}
}

View File

@@ -0,0 +1,228 @@
//
// DepthFirst.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;
namespace Mono.CodeContracts.Static.DataStructures {
static class DepthFirst {
public static void Visit<Node, EdgeInfo> (IGraph<Node, EdgeInfo> graph,
Predicate<Node> nodeStartVisitor,
EdgeVisitor<Node, EdgeInfo> edgeVisitor)
{
new Visitor<Node, EdgeInfo> (graph, nodeStartVisitor, edgeVisitor).VisitAll ();
}
public static void Visit<Node, EdgeInfo> (IGraph<Node, EdgeInfo> graph,
Node startNode,
Predicate<Node> nodeStartVisitor,
EdgeVisitor<Node, EdgeInfo> edgeVisitor)
{
new Visitor<Node, EdgeInfo> (graph, nodeStartVisitor, edgeVisitor).VisitSubGraphNonRecursive (startNode);
}
#region Nested type: Info
public class Info<Node> {
public readonly Node Parent;
public readonly int StartTime;
public int FinishTime;
public bool SourceOfBackEdge;
public bool TargetOfBackEdge;
public Info (Node parent, int startTime)
{
this.Parent = parent;
this.StartTime = startTime;
}
}
#endregion
#region Nested type: Visitor
public class Visitor<Node, Edge> {
private readonly HashSet<Tuple<Node, Edge, Node>> back_edges = new HashSet<Tuple<Node, Edge, Node>> ();
private readonly EdgeVisitor<Node, Edge> edge_visitor;
private readonly IGraph<Node, Edge> graph;
private readonly Dictionary<Node, Info<Node>> history = new Dictionary<Node, Info<Node>> ();
private readonly Action<Node> node_finish_visitor;
private readonly Predicate<Node> node_start_visitor;
private readonly Stack<SearchFrame> todo = new Stack<SearchFrame> ();
private int time;
public Visitor (IGraph<Node, Edge> graph, Predicate<Node> nodeStartVisitor, EdgeVisitor<Node, Edge> edgeVisitor)
: this (graph, nodeStartVisitor, null, edgeVisitor)
{
}
public Visitor (IGraph<Node, Edge> graph, Predicate<Node> nodeStartVisitor)
: this (graph, nodeStartVisitor, null, null)
{
}
public Visitor (IGraph<Node, Edge> graph, Predicate<Node> nodeStartVisitor, Action<Node> nodeFinishVisitor, EdgeVisitor<Node, Edge> edgeVisitor)
{
this.graph = graph;
this.node_start_visitor = nodeStartVisitor;
this.node_finish_visitor = nodeFinishVisitor;
this.edge_visitor = edgeVisitor;
}
public virtual void VisitAll ()
{
foreach (Node node in this.graph.Nodes)
this.VisitSubGraphNonRecursive (node);
}
public void VisitSubGraphNonRecursive (Node node)
{
ScheduleNode (node, default(Node));
IterativeDFS ();
}
private void IterativeDFS ()
{
while (this.todo.Count > 0) {
SearchFrame frame = this.todo.Peek ();
if (frame.Edges.MoveNext ()) {
Pair<Edge, Node> current = frame.Edges.Current;
VisitEdgeNonRecursive (frame.Info, frame.Node, current.Key, current.Value);
} else {
if (this.node_finish_visitor != null)
this.node_finish_visitor (frame.Node);
frame.Info.FinishTime = ++this.time;
this.todo.Pop ();
}
}
}
private void VisitEdgeNonRecursive(Info<Node> sourceInfo, Node source, Edge info, Node target)
{
if (!VisitEdgeCommon (sourceInfo, source, info, target))
ScheduleNode (target, source);
}
private void VisitEdge (Info<Node> sourceInfo, Node source, Edge info, Node target)
{
if (!VisitEdgeCommon (sourceInfo, source, info, target))
VisitSubGraph (target, source);
}
private bool VisitEdgeCommon(Info<Node> sourceInfo, Node source, Edge info, Node target )
{
if (this.edge_visitor != null)
this.edge_visitor(source, info, target);
Info<Node> targetInfo;
if (this.history.TryGetValue(target, out targetInfo))
{
if (targetInfo.FinishTime != 0)
return true;
targetInfo.TargetOfBackEdge = true;
sourceInfo.SourceOfBackEdge = true;
this.back_edges.Add(new Tuple<Node, Edge, Node>(source, info, target));
return true;
}
return false;
}
public void VisitSubGraph (Node node, Node parent)
{
if (this.history.ContainsKey (node))
return;
var info = new Info<Node> (parent, ++this.time);
this.history [node] = info;
if (this.node_start_visitor != null && !this.node_start_visitor (node))
return;
VisitSuccessors (info, node);
if (this.node_finish_visitor != null)
this.node_finish_visitor (node);
info.FinishTime = ++this.time;
}
public void ScheduleNode (Node node, Node parent)
{
if (this.history.ContainsKey (node))
return;
var info = new Info<Node> (parent, ++this.time);
this.history [node] = info;
if (this.node_start_visitor != null && !this.node_start_visitor (node))
return;
this.todo.Push (new SearchFrame (node, this.graph.Successors (node).GetEnumerator (), info));
}
private void VisitSuccessors (Info<Node> info, Node node)
{
foreach (var successor in this.graph.Successors (node))
VisitEdge (info, node, successor.Key, successor.Value);
}
public bool IsVisited (Node node)
{
return this.history.ContainsKey (node);
}
public bool IsBackEdge (Node source, Edge info, Node target)
{
return this.back_edges.Contains (new Tuple<Node, Edge, Node> (source, info, target));
}
public Info<Node> DepthFirstInfo (Node node)
{
return this.history [node];
}
#region Nested type: SearchFrame
private struct SearchFrame {
public readonly IEnumerator<Pair<Edge, Node>> Edges;
public readonly Info<Node> Info;
public readonly Node Node;
public SearchFrame (Node node, IEnumerator<Pair<Edge, Node>> edges, Info<Node> info)
{
this.Node = node;
this.Edges = edges;
this.Info = info;
}
}
#endregion
}
#endregion
}
}

View File

@@ -0,0 +1,90 @@
//
// DoubleDictionary.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.Collections.Generic;
using System.Linq;
namespace Mono.CodeContracts.Static.DataStructures {
class DoubleDictionary<A, B, C> : Dictionary<A, Dictionary<B, C>> {
public C this [A a, B b]
{
get { return base [a] [b]; }
set
{
Dictionary<B, C> dict;
if (!base.TryGetValue (a, out dict)) {
dict = new Dictionary<B, C> ();
base.Add (a, dict);
}
dict [b] = value;
}
}
public IEnumerable<A> Keys1
{
get { return base.Keys; }
}
public void Add (A a, B b, C value)
{
Dictionary<B, C> dict;
if (!base.TryGetValue (a, out dict)) {
dict = new Dictionary<B, C> ();
base.Add (a, dict);
}
dict.Add (b, value);
}
public IEnumerable<B> Keys2 (A a)
{
Dictionary<B, C> dict;
if (base.TryGetValue (a, out dict))
return dict.Keys;
return Enumerable.Empty<B> ();
}
public bool ContainsKey (A a, B b)
{
Dictionary<B, C> dict;
if (!base.TryGetValue (a, out dict))
return false;
return dict.ContainsKey (b);
}
public bool TryGetValue (A a, B b, out C value)
{
Dictionary<B, C> dict;
if (base.TryGetValue (a, out dict))
return dict.TryGetValue (b, out value);
value = default(C);
return false;
}
}
}

View File

@@ -0,0 +1,126 @@
//
// DoubleImmutableMap.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;
namespace Mono.CodeContracts.Static.DataStructures {
class DoubleImmutableMap<A, B, C>
where A : IEquatable<A>
where B : IEquatable<B> {
private readonly B[] EmptyCache = new B[0];
private readonly IImmutableMap<A, IImmutableMap<B, C>> map;
private DoubleImmutableMap (IImmutableMap<A, IImmutableMap<B, C>> map)
{
this.map = map;
}
public C this [A key1, B key2]
{
get
{
IImmutableMap<B, C> inner = this.map [key1];
if (inner == null)
return default(C);
return inner [key2];
}
}
public int Keys1Count
{
get { return this.map.Count; }
}
public IEnumerable<A> Keys1
{
get { return this.map.Keys; }
}
public DoubleImmutableMap<A, B, C> Add (A key1, B key2, C value)
{
IImmutableMap<B, C> immutableMap = this.map [key1] ?? ImmutableMap<B, C>.Empty;
return new DoubleImmutableMap<A, B, C> (this.map.Add (key1, immutableMap.Add (key2, value)));
}
public DoubleImmutableMap<A, B, C> RemoveAll (A key1)
{
return new DoubleImmutableMap<A, B, C> (this.map.Remove (key1));
}
public DoubleImmutableMap<A, B, C> Remove (A key1, B key2)
{
IImmutableMap<B, C> inner = this.map [key1];
if (inner == null)
return this;
IImmutableMap<B, C> newInner = inner.Remove (key2);
if (newInner == inner)
return this;
return new DoubleImmutableMap<A, B, C> (this.map.Add (key1, newInner));
}
public static DoubleImmutableMap<A, B, C> Empty (Func<A, int> uniqueIdGenerator)
{
return new DoubleImmutableMap<A, B, C> (ImmutableIntKeyMap<A, IImmutableMap<B, C>>.Empty (uniqueIdGenerator));
}
public bool Contains (A key1, B key2)
{
IImmutableMap<B, C> inner = this.map [key1];
if (inner == null)
return false;
return inner.ContainsKey (key2);
}
public bool ContainsKey1 (A key1)
{
return this.map.ContainsKey (key1);
}
public int Keys2Count (A key1)
{
if (key1 == null)
return 0;
IImmutableMap<B, C> inner = this.map [key1];
if (inner == null)
return 0;
return inner.Count;
}
public IEnumerable<B> Keys2 (A key1)
{
if (key1 == null)
return this.EmptyCache;
IImmutableMap<B, C> inner = this.map [key1];
if (inner == null)
return this.EmptyCache;
return inner.Keys;
}
}
}

View File

@@ -0,0 +1,42 @@
//
// Dummy.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;
namespace Mono.CodeContracts.Static.DataStructures {
struct Dummy : IEquatable<Dummy> {
public static readonly Dummy Value = new Dummy ();
#region IEquatable<Dummy> Members
public bool Equals (Dummy other)
{
return true;
}
#endregion
}
}

View File

@@ -0,0 +1,31 @@
//
// EdgeVisitor.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.
//
namespace Mono.CodeContracts.Static.DataStructures {
delegate void EdgeVisitor<Node, Info> (Node source, Info info, Node target);
}

View File

@@ -0,0 +1,55 @@
//
// GraphWrapper.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;
namespace Mono.CodeContracts.Static.DataStructures {
class GraphWrapper<Node, Info> : IGraph<Node, Info> {
private readonly IEnumerable<Node> nodes;
private readonly Func<Node, IEnumerable<Pair<Info, Node>>> successors;
public GraphWrapper (IEnumerable<Node> nodes, Func<Node, IEnumerable<Pair<Info, Node>>> successors)
{
this.nodes = nodes;
this.successors = successors;
}
#region Implementation of IGraph<Node,Info>
public IEnumerable<Node> Nodes
{
get { return this.nodes; }
}
public IEnumerable<Pair<Info, Node>> Successors (Node node)
{
return this.successors (node);
}
#endregion
}
}

View File

@@ -0,0 +1,36 @@
//
// IGraph.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.Collections.Generic;
namespace Mono.CodeContracts.Static.DataStructures {
interface IGraph<Node, EdgeInfo> {
IEnumerable<Node> Nodes { get; }
IEnumerable<Pair<EdgeInfo, Node>> Successors (Node node);
}
}

View File

@@ -0,0 +1,46 @@
//
// IImmutableIntMap.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;
namespace Mono.CodeContracts.Static.DataStructures {
public interface IImmutableIntMap<T> {
T this [int key] { get; }
T Any { get; }
IEnumerable<T> Values { get; }
IEnumerable<int> Keys { get; }
int Count { get; }
T Lookup (int key);
bool Contains (int key);
IImmutableIntMap<T> Add (int key, T value);
IImmutableIntMap<T> Remove (int key);
void Visit (Action<T> action);
void Visit (Action<int, T> action);
}
}

View File

@@ -0,0 +1,56 @@
//
// IImmutableMap.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;
namespace Mono.CodeContracts.Static.DataStructures {
interface IImmutableMap<K, V> {
V this [K key] { get; }
K AnyKey { get; }
IEnumerable<K> Keys { get; }
int Count { get; }
IImmutableMap<K, V> EmptyMap { get; }
IImmutableMap<K, V> Add (K key, V value);
IImmutableMap<K, V> Remove (K key);
bool ContainsKey (K key);
void Visit (Func<K, V, VisitStatus> func);
bool TryGetValue (K key, out V value);
IImmutableMapFactory<K, V> Factory();
}
internal interface IImmutableMapFactory<K, V> {
IImmutableMap<K, V> Empty { get; }
}
}

View File

@@ -0,0 +1,48 @@
//
// IImmutableSet.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;
namespace Mono.CodeContracts.Static.DataStructures {
interface IImmutableSet<T> {
T Any { get; }
int Count { get; }
IEnumerable<T> Elements { get; }
IImmutableSet<T> Add (T item);
IImmutableSet<T> AddRange (IEnumerable<T> item);
IImmutableSet<T> Remove (T item);
bool Contains (T item);
bool IsContainedIn (IImmutableSet<T> that);
IImmutableSet<T> Intersect (IImmutableSet<T> that);
IImmutableSet<T> Union (IImmutableSet<T> that);
void Visit (Action<T> visitor);
void Dump (TextWriter tw);
}
}

View File

@@ -0,0 +1,45 @@
//
// IIndexable.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.Collections.Generic;
namespace Mono.CodeContracts.Static.DataStructures {
interface IIndexable<out T> {
int Count { get; }
T this [int index] { get; }
}
static class IndexableExtensions {
public static IEnumerable<T> AsEnumerable<T>(this IIndexable<T> indexable)
{
for (int i = 0; i < indexable.Count; i++) {
yield return indexable[i];
}
}
}
}

View File

@@ -0,0 +1,35 @@
//
// IPropertyCollection.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.
//
namespace Mono.CodeContracts.Static.DataStructures {
internal interface IPropertyCollection {
bool Contains (TypedKey key);
void Add<T> (TypedKey key, T value);
bool TryGetValue<T> (TypedKey key, out T value);
}
}

View File

@@ -0,0 +1,35 @@
//
// IWorkList.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.
//
namespace Mono.CodeContracts.Static.DataStructures {
interface IWorkList<T> {
bool Add (T o);
bool IsEmpty ();
T Pull ();
}
}

View File

@@ -0,0 +1,138 @@
//
// ImmutableIntKeyMap.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.Linq;
namespace Mono.CodeContracts.Static.DataStructures {
class ImmutableIntKeyMap<K, V> : IImmutableMap<K, V>, IEquatable<IImmutableMap<K, V>> {
private readonly IImmutableIntMap<Pair<K, V>> immutable_int_map;
private readonly Func<K, int> keyConverter;
private ImmutableIntKeyMap (IImmutableIntMap<Pair<K, V>> map, Func<K, int> converter)
{
this.immutable_int_map = map;
this.keyConverter = converter;
}
#region Implementation of IImmutableMap<K,V>
public V this [K key]
{
get
{
V value;
TryGetValue (key, out value);
return value;
}
}
public K AnyKey
{
get { return Keys.First (); }
}
public IEnumerable<K> Keys
{
get
{
var res = new List<K> ();
this.immutable_int_map.Visit (data => res.Add (data.Key));
return res;
}
}
public int Count
{
get { return this.immutable_int_map.Count; }
}
public IImmutableMap<K, V> EmptyMap
{
get { return Empty (this.keyConverter); }
}
public IImmutableMap<K, V> Add (K key, V value)
{
return new ImmutableIntKeyMap<K, V> (this.immutable_int_map.Add (this.keyConverter (key), new Pair<K, V> (key, value)), this.keyConverter);
}
public IImmutableMap<K, V> Remove (K key)
{
return new ImmutableIntKeyMap<K, V> (this.immutable_int_map.Remove (this.keyConverter (key)), this.keyConverter);
}
public bool ContainsKey (K key)
{
return this.immutable_int_map.Contains (this.keyConverter (key));
}
public bool TryGetValue(K key, out V value)
{
Pair<K, V> pair = this.immutable_int_map[this.keyConverter(key)];
if (pair != null)
return true.With(pair.Value, out value);
return false.Without(out value);
}
public void Visit (Func<K, V, VisitStatus> func)
{
this.immutable_int_map.Visit (data => func (data.Key, data.Value));
}
#endregion
#region Implementation of IEquatable<IImmutableMap<K,V>>
public bool Equals (IImmutableMap<K, V> other)
{
return this == other;
}
#endregion
public static IImmutableMap<K, V> Empty (Func<K, int> keyConverter)
{
return new ImmutableIntKeyMap<K, V> (ImmutableIntMap<Pair<K, V>>.Empty, keyConverter);
}
public IImmutableMapFactory<K, V> Factory ()
{
return new MapFactory (this.keyConverter);
}
private class MapFactory : IImmutableMapFactory<K,V> {
private readonly Func<K, int> keyConverter;
public MapFactory (Func<K, int> keyConverter)
{
this.keyConverter = keyConverter;
}
public IImmutableMap<K, V> Empty { get { return ImmutableIntKeyMap<K, V>.Empty (keyConverter);}}
}
}
}

View File

@@ -0,0 +1,36 @@
//
// ImmutableIntMap.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 Mono.CodeContracts.Static.DataStructures.Patricia;
namespace Mono.CodeContracts.Static.DataStructures {
public static class ImmutableIntMap<T>
{
public static readonly IImmutableIntMap<T> Empty = EmptyNode<T>.Instance;
}
}

View File

@@ -0,0 +1,162 @@
//
// ImmutableMap.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.Linq;
namespace Mono.CodeContracts.Static.DataStructures {
class ImmutableMap<K, V> : IImmutableMap<K, V>
where K : IEquatable<K> {
public static readonly ImmutableMap<K, V> Empty = new ImmutableMap<K, V> (ImmutableIntMap<Sequence<Pair<K, V>>>.Empty, 0, null);
private readonly int count;
private readonly IImmutableIntMap<Sequence<Pair<K, V>>> immutable_int_map;
private readonly Sequence<K> keys;
private ImmutableMap (IImmutableIntMap<Sequence<Pair<K, V>>> map, int count, Sequence<K> keys)
{
this.keys = keys;
this.count = count;
this.immutable_int_map = map;
}
#region Implementation of IImmutableMap<K,V>
public V this [K key]
{
get
{
V value;
return TryGetValue (key, out value) ? value : default(V);
}
}
public bool TryGetValue (K key, out V value)
{
for (Sequence<Pair<K, V>> list = this.immutable_int_map[key.GetHashCode ()]; list != null; list = list.Tail)
{
K k = list.Head.Key;
if (key.Equals (k))
return true.With (list.Head.Value, out value);
}
return false.Without (out value);
}
public K AnyKey
{
get { return this.keys.Head; }
}
public IEnumerable<K> Keys
{
get { return this.keys.AsEnumerable (); }
}
public int Count
{
get { return this.immutable_int_map.Count; }
}
public IImmutableMap<K, V> EmptyMap
{
get { return Empty; }
}
public IImmutableMap<K, V> Add (K key, V value)
{
int hashCode = key.GetHashCode ();
Sequence<Pair<K, V>> cur = this.immutable_int_map [hashCode];
Sequence<Pair<K, V>> newList = Remove (cur, key).Cons (new Pair<K, V> (key, value));
int diff = newList.Length () - cur.Length ();
Sequence<K> newKeys = diff == 0 ? this.keys : this.keys.Cons (key);
return new ImmutableMap<K, V> (this.immutable_int_map.Add (hashCode, newList), this.count + diff, newKeys);
}
public IImmutableMap<K, V> Remove (K key)
{
int hashCode = key.GetHashCode ();
Sequence<Pair<K, V>> from = this.immutable_int_map [hashCode];
if (from == null)
return this;
Sequence<Pair<K, V>> newList = Remove (from, key);
if (newList == from)
return this;
Sequence<K> newKeys = RemoveKey (key, this.keys);
if (newList == null)
return new ImmutableMap<K, V> (this.immutable_int_map.Remove (hashCode), this.count - 1, newKeys);
return new ImmutableMap<K, V> (this.immutable_int_map.Add (hashCode, newList), this.count - 1, newKeys);
}
public bool ContainsKey (K key)
{
return this.immutable_int_map [key.GetHashCode ()].AsEnumerable ().Any (pair => key.Equals (pair.Key));
}
public void Visit (Func<K, V, VisitStatus> func)
{
this.immutable_int_map.Visit (list => {
foreach (var pair in list.AsEnumerable ())
func (pair.Key, pair.Value);
});
}
private Sequence<Pair<K, V>> Remove (Sequence<Pair<K, V>> from, K key)
{
if (from == null)
return null;
if (key.Equals (from.Head.Key))
return from.Tail;
Sequence<Pair<K, V>> tail = Remove (from.Tail, key);
return tail == from.Tail ? from : tail.Cons (from.Head);
}
private static Sequence<K> RemoveKey (K key, Sequence<K> keys)
{
if (keys == null)
throw new InvalidOperationException ();
if (key.Equals (keys.Head))
return keys.Tail;
return RemoveKey (key, keys.Tail).Cons (keys.Head);
}
#endregion
public IImmutableMapFactory<K, V> Factory ()
{
return new MapFactory ();
}
private class MapFactory : IImmutableMapFactory<K, V>
{
public IImmutableMap<K, V> Empty { get { return ImmutableMap<K,V>.Empty;}}
}
}
}

View File

@@ -0,0 +1,178 @@
//
// ImmutableSet.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;
namespace Mono.CodeContracts.Static.DataStructures {
class ImmutableSet<T> : IImmutableSet<T>
where T : IEquatable<T> {
private readonly IImmutableMap<T, Dummy> underlying;
private ImmutableSet (IImmutableMap<T, Dummy> immutableMap)
{
this.underlying = immutableMap;
}
#region Implementation of IImmutableSet<T>
public T Any
{
get { return this.underlying.AnyKey; }
}
public int Count
{
get { return this.underlying.Count; }
}
public IEnumerable<T> Elements
{
get { return this.underlying.Keys; }
}
public IImmutableSet<T> Add (T item)
{
return new ImmutableSet<T> (this.underlying.Add (item, Dummy.Value));
}
public IImmutableSet<T> AddRange(IEnumerable<T> seq)
{
var map = this.underlying;
foreach (var item in seq)
map = map.Add(item, Dummy.Value);
return new ImmutableSet<T>(map);
}
public IImmutableSet<T> Remove (T item)
{
return new ImmutableSet<T> (this.underlying.Remove (item));
}
public bool Contains (T item)
{
return this.underlying.ContainsKey (item);
}
public bool IsContainedIn (IImmutableSet<T> that)
{
if (Count > that.Count)
return false;
bool result = true;
this.underlying.Visit ((e, dummy) => {
if (that.Contains (e))
return VisitStatus.ContinueVisit;
result = false;
return VisitStatus.StopVisit;
});
return result;
}
public IImmutableSet<T> Intersect (IImmutableSet<T> that)
{
if (this == that)
return this;
if (Count == 0)
return this;
IImmutableSet<T> set;
IImmutableSet<T> larger;
if (Count < that.Count) {
set = this;
larger = that;
} else {
if (that.Count == 0)
return that;
set = that;
larger = this;
}
IImmutableSet<T> result = set;
set.Visit ((e) => {
if (!larger.Contains (e))
result = result.Remove (e);
});
return result;
}
public IImmutableSet<T> Union (IImmutableSet<T> that)
{
if (this == that)
return this;
if (Count == 0)
return that;
IImmutableSet<T> smaller;
IImmutableSet<T> larger;
if (Count < that.Count) {
smaller = this;
larger = that;
} else {
if (that.Count == 0)
return this;
smaller = that;
larger = this;
}
IImmutableSet<T> result = larger;
smaller.Visit (e => { result = result.Add (e); });
return result;
}
public void Visit (Action<T> visitor)
{
this.underlying.Visit ((elem, dummy) => {
visitor (elem);
return VisitStatus.ContinueVisit;
});
}
public void Dump (TextWriter tw)
{
tw.Write ("{");
bool first = true;
foreach (T key in this.underlying.Keys) {
if (!first)
tw.Write (", ");
else
first = false;
tw.Write ("{0}", key);
}
tw.WriteLine ("}");
}
public static IImmutableSet<T> Empty ()
{
return new ImmutableSet<T> (ImmutableMap<T, Dummy>.Empty);
}
public static IImmutableSet<T> Empty (Func<T, int> keyConverter)
{
return new ImmutableSet<T> (ImmutableIntKeyMap<T, Dummy>.Empty (keyConverter));
}
#endregion
}
}

Some files were not shown because too many files have changed in this diff Show More