private bool CheckCorrespondence(IsomorphicInfo isomorphicInfo) { bool result = true; foreach (var a in isomorphicInfo.As) { foreach (var outgoingPair in a.State.Outgoing) { var isOk = isomorphicInfo.StatesCorrespondence.GetSecond(outgoingPair.Value.GetTransRes(random).DestState) == isomorphicInfo.StatesCorrespondence.GetSecond(outgoingPair.Value.FromState).Outgoing. Where( o => o.Value.ActionCore == isomorphicInfo.InputCorrespondence.GetSecond( new InputInfo(outgoingPair.Value.ActionCore)).Input).FirstOrDefault().Value.GetTransRes(random).DestState; if (isOk) { var w = outgoingPair.Value.GetTransRes(random).Output; var w1 = isomorphicInfo.StatesCorrespondence.GetSecond(a.State).Outgoing.Where( o => o.Value.ActionCore == isomorphicInfo.InputCorrespondence.GetSecond( new InputInfo(outgoingPair.Value.ActionCore)).Input).FirstOrDefault().Value.GetTransRes(random).Output; isomorphicInfo.OutputCorrespondence.AddAssociation(w, w1); } else { result = false; break; } } if (!result) { break; } } return(result); }
private bool RecursiveInput( List <InputInfo> Zs, List <InputInfo> Xs, IsomorphicInfo isomorphicInfo) { bool result = false; if (Zs.Count > 0) { var z = Zs[0]; var x = z.GetFirst(Xs); if (x != null) { isomorphicInfo.InputCorrespondence.AddAssociation(z, x); result = RecursiveInput( new List <InputInfo>(Zs.Where(i => i.Input != z.Input)),//.Skip(1)), new List <InputInfo>(Xs.Where(i => i.Input != x.Input)), isomorphicInfo); if (!result) { z.Rejected.Add(x.Input); isomorphicInfo.InputCorrespondence.RemoveAssociationFirst(z); foreach (var zz in Zs.Skip(1)) { zz.Rejected.Clear(); } result = RecursiveInput(Zs, Xs, isomorphicInfo); } } } else { result = RecursiveState( isomorphicInfo.As, isomorphicInfo.Bs, isomorphicInfo); } return(result); }
private bool RecursiveState( List <StateInfo> As, List <StateInfo> Bs, IsomorphicInfo isomorphicInfo) { bool result = false; if (As.Count > 0) { var a = As[0]; var b = a.GetFirstPotential(Bs); if (b != null) { isomorphicInfo.StatesCorrespondence.AddAssociation(a.State, b.State); result = RecursiveState(new List <StateInfo>(As.Where(s => s.State.StateCore != a.State.StateCore)),//Skip(1)), new List <StateInfo>(Bs.Where(s => s.State.StateCore != b.State.StateCore)), isomorphicInfo); if (!result) { a.Rejected.Add(b.State); isomorphicInfo.StatesCorrespondence.RemoveAssociationFirst(a.State); foreach (var aa in As.Skip(1)) { aa.Rejected.Clear(); } result = RecursiveState(As, Bs, isomorphicInfo); } } } else { if (isomorphicInfo.StatesCorrespondence.Count() == isomorphicInfo.As.Count) { result = CheckCorrespondence(isomorphicInfo); } } return(result); }
public IsomorphicInfo IsIsomorphic(FiniteStateMachine <TInput, TOutput> other) { BidirectionalDictionary <FSMState <TInput, TOutput>, FSMState <TInput, TOutput> > statesCorrespondence = new BidirectionalDictionary <FSMState <TInput, TOutput>, FSMState <TInput, TOutput> >(); BidirectionalDictionary <TInput, TInput> inputCorrespondence = new BidirectionalDictionary <TInput, TInput>(); BidirectionalDictionary <TOutput, TOutput> outputCorrespondence = new BidirectionalDictionary <TOutput, TOutput>(); // У изоморфных автоматов должно совпадать: // - число состояний // - величина входного алфавита // - величина выходного автомата bool resultFlag = this.stateSet.Count == other.stateSet.Count && this.inputSet.Count == other.inputSet.Count && this.outputSet.Count == other.outputSet.Count; IsomorphicInfo result = null; if (resultFlag) { EventableDictionary <FSMState <TInput, TOutput>, StateInfo> ThisStatistics = new EventableDictionary <FSMState <TInput, TOutput>, StateInfo>(stateSet.Count); EventableDictionary <FSMState <TInput, TOutput>, StateInfo> OtherStatistics = new EventableDictionary <FSMState <TInput, TOutput>, StateInfo>(other.stateSet.Count); CalcStats(stateSet, ThisStatistics); CalcStats(other.stateSet, OtherStatistics); foreach (var statState in ThisStatistics) { foreach (var statOtherState in OtherStatistics) { if (statState.Value.InputCount == statOtherState.Value.InputCount && statState.Value.LoopCount == statOtherState.Value.LoopCount && statState.Value.OutputCount == statOtherState.Value.OutputCount) { statState.Value.Potential.Add(statOtherState.Key); statOtherState.Value.Potential.Add(statState.Key); } } if (statState.Value.Potential.Count == 0) { // Если у какого-нибудь состояния нет потенциальных вариантов на замену, то наша затея - фигня. resultFlag = false; break; } } if (resultFlag) { result = new IsomorphicInfo(); // Запихиваем в соответствия те пары состояний, про которые уже всё понятно foreach (var statItem in ThisStatistics) { if (statItem.Value.Potential.Count == 1) { if (!statesCorrespondence.ExistsFirst(statItem.Key) && !statesCorrespondence.ExistsSecond(statItem.Value.Potential[0])) { statesCorrespondence.AddAssociation(statItem.Key, statItem.Value.Potential[0]); } else { result = null; break; } } } if (result != null) { result.As.AddRange( stateSet.Select( s => ThisStatistics.Where(ss => ss.Key.StateCore == s.StateCore).First().Value)); result.Bs.AddRange( other.stateSet.Select( s => OtherStatistics.Where(ss => ss.Key.StateCore == s.StateCore).First().Value)); result.Zs.AddRange(inputSet.Select(i => new InputInfo(i))); result.Xs.AddRange(other.inputSet.Select(i => new InputInfo(i))); if (!RecursiveInput( new List <InputInfo>(inputSet.Select(i => new InputInfo(i))), new List <InputInfo>(other.inputSet.Select(i => new InputInfo(i))), result)) { result = null; } } } } return(result); }