/// <summary> /// Stores information about state pairs and its transitions. /// Used by HSI method to generate harmonized sets. /// </summary> /// <summary> /// Apply fsm inputs and set points from a state-pair to another one. /// </summary> public List <FailnessRecord> GetFailnessTable() { //if (this.failnessTable != null) // return this.failnessTable; this.failnessTable = new List <FailnessRecord>(); StatePair[] pairs = this.GetStatePairGroup(); for (int i = 0; i < pairs.Length; i++) { StatePair pair = pairs[i]; for (int j = 0; j < this.fsm.InputAlphabet.Count; j++) { FailnessRecord record = new FailnessRecord(); record.SourcePair = pair; record.Input = this.fsm.InputAlphabet[j]; String outputA = String.Empty, outputB = String.Empty; State targetA = null, targetB = null; //gets record target foreach (Transition t in this.fsm.Transitions.Where(x => x.Input == record.Input)) { if (t.SourceState == pair.StateA) { targetA = t.TargetState; outputA = t.Output; } else if (t.SourceState == pair.StateB) { targetB = t.TargetState; outputB = t.Output; } } if (targetA == null || targetB == null) { record.Status = Failness.Invalid; } else if (outputA != outputB) { record.Status = Failness.Fail; } else { record.Status = Failness.Valid; } record.TargetPair = pairs.Where(x => (x.StateA == targetA && x.StateB == targetB) || (x.StateB == targetA && x.StateA == targetB)).FirstOrDefault(); this.failnessTable.Add(record); } } return(failnessTable); }
/// <summary> /// Returns input which made state pair failed. If current /// State pair is not fail, locate the shortest sequence to /// reach a failed state pair. /// </summary> private String[] FindShortestInputToFail(List <FailnessRecord> failnessTable, StatePair[] statePairGroup, StatePair sp) { IEnumerable <FailnessRecord> foundRecords = from FailnessRecord f in failnessTable where f.SourcePair.Equals(sp) && f.Status == Failness.Fail select f; //it is fail. get input which made it fail if (foundRecords.Count() > 0) { FailnessRecord record = foundRecords.First(); //will never be null return(new String[] { record.Input }); } else //is invalid or valid { //make a new query, so we can proceed on the valid way foundRecords = from FailnessRecord f in failnessTable where f.SourcePair.Equals(sp) && f.Status == Failness.Valid select f; //find available sequences to fail List <String[]> foundSequences = new List <String[]>(); foreach (FailnessRecord f in foundRecords) { String[] sequence = FindShortestInputToFail(failnessTable, statePairGroup, f.TargetPair); if (sequence != null) { List <String> newSequence = new List <String>(); newSequence.Add(f.Input); newSequence.AddRange(sequence); foundSequences.Add(newSequence.ToArray()); } } //return the shortest sequence String[] bestFit = null; foreach (String[] sequence in foundSequences) { if (sequence.Length < 2) { continue; } if (bestFit == null || bestFit.Length > sequence.Length) { bestFit = sequence; } } return(bestFit); } }