public void Redundant_Partition_Test()
        {
            var input = new LinkedListWithInit <int> {
                1, 2, 3, 4, 5, 6
            };
            var pr = new PartitionRefinement <int> (new List <LinkedList <int> > {
                input
            });

            Assert.AreEqual(1, pr.Partition.Count);

            var divided = pr.Refine(new List <int> {
                1, 2, 3, 4, 5, 6
            });

            Assert.IsFalse(divided.Any());

            var divided_2 = pr.Refine(new List <int> {
                2, 3, 4, 5, 6
            });

            Assert.IsTrue(divided_2.Any());

            var divided_3 = pr.Refine(new List <int> {
                1
            });

            Assert.AreEqual(0, divided_3.Count);
            Assert.AreEqual(2, pr.Partition.Count);
        }
        public void Multiple_Refines_Test()
        {
            var pr = new PartitionRefinement <int> (new List <LinkedList <int> > {
                new LinkedListWithInit <int> {
                    1, 2, 3
                },
                new LinkedListWithInit <int> {
                    4, 5
                },
                new LinkedListWithInit <int> {
                    6
                }
            });
            var res1 = pr.Refine(new List <int> {
                4
            });

            Assert.AreEqual(4, pr.Partition.Count);
            foreach (var s in pr.Partition)
            {
                foreach (var el in s)
                {
                    Console.Write(el + ", ");
                    Assert.AreSame(s, pr[el]);
                }
                Console.WriteLine();
            }
        }
        public void Access_Operator_Test()
        {
            var input = new LinkedListWithInit <int> {
                1, 2, 3, 4, 5, 6
            };
            var pr = new PartitionRefinement <int> (new List <LinkedList <int> > {
                input
            });

            Assert.AreSame(input, pr [1]);
            Assert.AreSame(input, pr [6]);

            var divided = pr.Refine(new List <int> {
                1, 2, 3
            });
            var first  = divided [0].Difference;
            var second = divided [0].Intersection;

            foreach (var el in first)
            {
                Assert.AreSame(first, pr [el]);
            }
            foreach (var el in second)
            {
                Assert.AreSame(second, pr [el]);
            }

            var devided_2 = pr.Refine(new List <int> {
                3, 4
            });

            Assert.AreEqual(2, devided_2.Count);
            var firstIntersect  = devided_2 [0].Intersection;
            var firstDiff       = devided_2 [0].Difference;
            var secondIntersect = devided_2 [1].Intersection;
            var secondDiff      = devided_2 [1].Difference;

            foreach (var el in firstIntersect)
            {
                Assert.AreSame(firstIntersect, pr [el]);
            }
            foreach (var el in firstDiff)
            {
                Assert.AreSame(firstDiff, pr [el]);
            }
            foreach (var el in secondIntersect)
            {
                Assert.AreSame(secondIntersect, pr [el]);
            }
            foreach (var el in secondDiff)
            {
                Assert.AreSame(secondDiff, pr [el]);
            }
        }
        public void Basic_Partition_Test()
        {
            var input = new LinkedListWithInit <int> {
                1, 2, 3, 4, 5, 6
            };
            var pr = new PartitionRefinement <int> (new List <LinkedList <int> > {
                input
            });

            Assert.AreEqual(1, pr.Partition.Count);

            var divided = pr.Refine(new List <int> {
                1, 2, 3
            });

            Assert.AreEqual(1, divided.Count);
            Assert.AreEqual(2, pr.Partition.Count);
            Assert.AreSame(input, divided [0].Difference);
            Assert.IsTrue(ListEquals(new LinkedListWithInit <int> {
                1, 2, 3
            }, divided[0].Intersection));
            Assert.IsTrue(ListEquals(new LinkedListWithInit <int> {
                4, 5, 6
            }, divided[0].Difference));

            var divided_2 = pr.Refine(new List <int> {
                3, 4
            });

            Assert.AreEqual(2, divided_2.Count);
            Assert.AreEqual(4, pr.Partition.Count);

            var divided_3 = pr.Refine(new List <int> {
                1, 6
            });

            Assert.AreEqual(2, divided_3.Count);
            Assert.AreEqual(6, pr.Partition.Count);

            var divided_4 = pr.Refine(new List <int> {
                1, 2, 3, 4, 5, 6
            });

            Assert.AreEqual(0, divided_4.Count);
            Assert.AreEqual(6, pr.Partition.Count);
        }
Пример #5
0
        private static MinimizedDfa <TSymbol> BuildNewDfa <TDfa, TDfaState, TSymbol> (TDfa dfa, PartitionRefinement <TDfaState> partition, IList <TDfaState> stateList)
            where TDfa : AbstractDfa <TDfaState, TSymbol> where TDfaState : AbstractDfaState <TDfaState, TSymbol> where TSymbol : IComparable <TSymbol>, IEquatable <TSymbol>
        {
            var oldToSimpleState            = new Dictionary <TDfaState, SimpleState <TSymbol> >();
            var setToState                  = new Dictionary <LinkedList <TDfaState>, SimpleState <TSymbol> >();
            var simpleStateToMinimizedState = new Dictionary <SimpleState <TSymbol>, MinimizedDfaState <TSymbol> >();

            foreach (var oldState in stateList)
            {
                var set = partition [oldState];
                Debug.Assert(set.Count != 0);

                if (!setToState.ContainsKey(set))
                {
                    var newSimpleState = new SimpleState <TSymbol>();
                    setToState [set] = newSimpleState;
                    simpleStateToMinimizedState [newSimpleState] = new MinimizedDfaState <TSymbol>();

                    newSimpleState.Accepting = oldState.Accepting;
                }

                oldToSimpleState [oldState] = setToState [set];
            }

            foreach (var oldState in stateList)
            {
                var stateA = oldToSimpleState [oldState];

                foreach (var transtion in oldState.Transitions)
                {
                    var stateB = oldToSimpleState [transtion.Value];

                    if (!stateA.Edges.ContainsKey(transtion.Key))
                    {
                        stateA.Edges [transtion.Key] = stateB;
                    }
                }
            }

            foreach (var statePair in simpleStateToMinimizedState)
            {
                var simpleState    = statePair.Key;
                var minimizedState = statePair.Value;

                minimizedState._accepting = simpleState.Accepting;

                var newTransitions = new List <KeyValuePair <TSymbol, MinimizedDfaState <TSymbol> > >();

                foreach (var edge in simpleState.Edges)
                {
                    var newEdge = new KeyValuePair <TSymbol, MinimizedDfaState <TSymbol> >(edge.Key, simpleStateToMinimizedState[edge.Value]);
                    newTransitions.Add(newEdge);
                }

                newTransitions.Sort(CompareByKey <TDfa, TDfaState, TSymbol>);

                minimizedState._transitions = newTransitions.ToArray();
            }

            var newMinimizedDfa = new MinimizedDfa <TSymbol>();
            var startSet        = partition [dfa.Start];

            newMinimizedDfa._start = simpleStateToMinimizedState [setToState [startSet]];

            return(newMinimizedDfa);
        }
Пример #6
0
        private static MinimizedDfa <TSymbol> HopcroftAlgorithm <TDfa, TDfaState, TSymbol> (TDfa dfa)
            where TDfa : AbstractDfa <TDfaState, TSymbol> where TDfaState : AbstractDfaState <TDfaState, TSymbol> where TSymbol : IComparable <TSymbol>, IEquatable <TSymbol>
        {
            IList <TDfaState> stateList = PrepareStateList <TDfa, TDfaState, TSymbol>(dfa);

            TSymbol[] alphabet    = AlphabetRanges <TDfaState, TSymbol>(stateList);
            var       stateGroups = new Dictionary <uint, LinkedList <TDfaState> >();

            foreach (var state in stateList)
            {
                if (!stateGroups.ContainsKey(state.Accepting))
                {
                    stateGroups[state.Accepting] = new LinkedList <TDfaState>();
                }

                stateGroups [state.Accepting].AddLast(state);
            }

            var partition = new PartitionRefinement <TDfaState>(stateGroups.Values.ToList());

            ISet <LinkedList <TDfaState> > queue = new HashSet <LinkedList <TDfaState> >();

            foreach (var state in stateList)
            {
                //Console.WriteLine (state.GetId () + " " + state.Transitions[0].Value.GetId() + " " + state.Transitions[1].Value.GetId());
                var set = partition[state];
                if (state.Accepting != 0 && !queue.Contains(set))
                {
                    queue.Add(set);
                }
            }

            while (queue.Count > 0)
            {
                var mainSet = new LinkedList <TDfaState> ();
                foreach (var elem in queue.First())
                {
                    mainSet.AddLast(elem);
                }
                queue.Remove(queue.First());

                foreach (TSymbol c in alphabet)
                {
                    var prevSet = new LinkedList <TDfaState>();

                    foreach (var state in stateList)
                    {
                        var deltaState = state.Transitions[SimpleBinarySearch <TDfaState, TSymbol> (state.Transitions, c)].Value; //or upperbound?
                        //if(partition[deltaState] == mainSet)
                        if (mainSet.Contains(deltaState))
                        {
                            prevSet.AddFirst(state);
                        }
                    }

                    if (prevSet.Count == 0)
                    {
                        continue;
                    }

                    var setsPartition = partition.Refine(prevSet);

                    foreach (var setPartition in setsPartition)
                    {
                        if (setPartition.Difference.Count == 0 || setPartition.Intersection.Count == 0)
                        {
                            continue;
                        }

                        if (queue.Contains(setPartition.Difference))
                        {
                            queue.Add(setPartition.Intersection);
                        }
                        else
                        {
                            if (setPartition.Difference.Count <= setPartition.Intersection.Count)
                            {
                                queue.Add(setPartition.Difference);
                            }
                            else
                            {
                                queue.Add(setPartition.Intersection);
                            }
                        }
                    }
                }
            }


            var newDfa = BuildNewDfa <TDfa, TDfaState, TSymbol>(dfa, partition, stateList);

            return(newDfa);
        }