/// <summary> /// ARMC constructor. /// </summary> /// <param name="config">Configuration.</param> public ARMC(Config config) : this(SSA <SYMBOL> .Parse(config.InitFilePath), SSA <SYMBOL> .Parse(config.BadFilePath), config.TauFilePaths.Select(path => SST <SYMBOL> .Parse(path)).ToArray(), config) { }
/// <summary> /// Compose transducers T1 and T2, resulting in transducer equivalent to applying T2 after T1. /// </summary> public static SST <SYMBOL> Compose(SST <SYMBOL> tau1, SST <SYMBOL> tau2) { if (tau1.Algebra != tau2.Algebra) { throw SSTException.IncompatibleAlphabets(); } LabelAlgebra <SYMBOL> algebra = tau1.Algebra; var stack = new Stack <Tuple <int, int> >(); var finalStates = new List <int>(); var moves = new List <Move <Label <SYMBOL> > >(); var stateDict = new Dictionary <Tuple <int, int>, int>(); int id = 0; var init = new Tuple <int, int>(tau1.InitialState, tau2.InitialState); stateDict[init] = id++; stack.Push(init); while (stack.Count > 0) { Tuple <int, int> sourcePair = stack.Pop(); int state1 = sourcePair.Item1; int state2 = sourcePair.Item2; foreach (Move <Label <SYMBOL> > move1 in tau1.GetMovesFrom(state1)) { foreach (Move <Label <SYMBOL> > move2 in tau2.GetMovesFrom(state2)) { Label <SYMBOL> newLabel = algebra.Combine(move1.Label, move2.Label); if (!algebra.IsSatisfiable(newLabel)) { continue; } var targetPair = new Tuple <int, int>(move1.TargetState, move2.TargetState); int targetState; if (!stateDict.TryGetValue(targetPair, out targetState)) { stateDict[targetPair] = targetState = id++; stack.Push(targetPair); if (tau1.IsFinalState(move1.TargetState) && tau2.IsFinalState(move2.TargetState)) { finalStates.Add(targetState); } } moves.Add(new Move <Label <SYMBOL> >(stateDict[sourcePair], targetState, newLabel)); } } } return(new SST <SYMBOL>(0, finalStates, moves)); }
public PredicateAbstraction(Config config, SSA <SYMBOL> init = null, SSA <SYMBOL> bad = null, SST <SYMBOL>[] taus = null) { var initPreds = new List <SSA <SYMBOL> >(); /* add Init? */ if (config.InitialPredicate == Config.InitPred.Init || config.InitialPredicate == Config.InitPred.Both) { initPreds.Add(init ?? SSA <SYMBOL> .Parse(config.InitFilePath)); } /* add Bad? */ if (config.InitialPredicate == Config.InitPred.Bad || config.InitialPredicate == Config.InitPred.Both) { initPreds.Add(bad ?? SSA <SYMBOL> .Parse(config.BadFilePath)); } /* add transducer domains and/or ranges? */ SST <SYMBOL>[] ssts = taus ?? config.TauFilePaths.Select(path => SST <SYMBOL> .Parse(path)).ToArray(); if (config.IncludeGuard) { foreach (SST <SYMBOL> sst in ssts) { initPreds.Add(sst.Domain()); } } if (config.IncludeAction) { foreach (SST <SYMBOL> sst in ssts) { initPreds.Add(sst.Range()); } } /* ensure that the automata contain no epsilon transitions and have disjunct sets of states */ predicateAutomata = new Set <SSA <SYMBOL> >(); int offset = 0; foreach (SSA <SYMBOL> pred in initPreds) { SSA <SYMBOL> normPred = pred.RemoveEpsilons().Normalize(offset); predicateAutomata.Add(normPred); offset += normPred.States.Count(); } forward = (config.LanguageDirection == Config.Direction.Forward); heuristic = config.Heuristic; ignoredLabels = new Set <int>(); // remains empty if no heuristic used }
/// <summary> /// Constructs transducer that models the inverse relation. /// </summary> public SST <SYMBOL> Invert() { var result = new SST <SYMBOL>(automaton.RelpaceAllGuards(label => label.Invert())); if (Name != null) { string marker = "<sup>-1</sup>"; if (Name.EndsWith(marker)) { result.Name = Name.Substring(0, Name.Length - marker.Length); } else { result.Name = Name + marker; } } if (StateNames != null) { result.StateNames = new Dictionary <int, string>(StateNames); } return(result); }
/// <summary> /// ARMC constructor. /// </summary> /// <param name="init">SSA representing initial states.</param> /// <param name="bad">SSA representing bad states.</param> /// <param name="tau">SST representing transition.</param> /// <param name="config">Configuration.</param> public ARMC(SSA <SYMBOL> init, SSA <SYMBOL> bad, SST <SYMBOL> tau, Config config) : this(init, bad, new SST <SYMBOL>[] { tau }, config) { }
/// <summary> /// ARMC constructor. /// </summary> /// <param name="init">SSA representing initial states.</param> /// <param name="bad">SSA representing bad states.</param> /// <param name="tau">SST representing transition.</param> /// <param name="configFileName">Configuration file path.</param> public ARMC(SSA <SYMBOL> init, SSA <SYMBOL> bad, SST <SYMBOL> tau, string configFileName) : this(init, bad, new SST <SYMBOL>[] { tau }, new Config(configFileName)) { }
/// <summary> /// ARMC constructor. /// </summary> /// <param name="init">SSA representing initial states.</param> /// <param name="bad">SSA representing bad states.</param> /// <param name="tau">SST representing transition.</param> public ARMC(SSA <SYMBOL> init, SSA <SYMBOL> bad, SST <SYMBOL> tau) : this(init, bad, new SST <SYMBOL>[] { tau }, new Config()) { }
/// <summary> /// ARMC constructor. /// </summary> /// <param name="init">SSA representing initial states.</param> /// <param name="bad">SSA representing bad states.</param> /// <param name="taus">SSTs whose composition represents transition.</param> /// <param name="config">Configuration.</param> public ARMC(SSA <SYMBOL> init, SSA <SYMBOL> bad, SST <SYMBOL>[] taus, Config config) { /* merge alphabets */ Set <SYMBOL> alphabet = init.Alphabet + bad.Alphabet + taus.Select(tau => tau.Alphabet).Aggregate(Set <SYMBOL> .Union); init.Alphabet = alphabet; bad.Alphabet = alphabet; for (int i = 0; i < taus.Length; i++) { taus[i].Alphabet = alphabet; } if (config.PredicateLanguages == config.FiniteLengthLanguages) // sanity check { throw ConfigException.AbstractionNotChosen(); } this.init = init; this.bad = bad; this.tau = SST <SYMBOL> .Union(taus); this.tauInv = tau.Invert(); this.abstr = config.PredicateLanguages ? (Abstraction <SYMBOL>) new PredicateAbstraction <SYMBOL>(config, init, bad, taus) : new FiniteLengthAbstraction <SYMBOL>(config, init, bad, taus); this.verbose = config.Verbose; this.printAutomata = config.PrintAutomata; this.outputDir = config.OutputDirectory; this.format = config.AutomataFormat; this.imgExt = (config.ImageFormat == null) ? "" : config.ImageFormat.ToString(); this.timeout = config.Timeout.Ticks; this.stopwatch = new Stopwatch(); this.loops = 0; if (outputDir != "") { /* clear output directory */ DirectoryInfo dirInfo = Directory.CreateDirectory(outputDir); foreach (FileInfo fi in dirInfo.EnumerateFiles()) { fi.Delete(); } foreach (DirectoryInfo di in dirInfo.EnumerateDirectories()) { di.Delete(true); } } if (printAutomata) { /* print input automata and configuration */ string dir = Path.Combine(outputDir, "armc-input"); Directory.CreateDirectory(dir); PrintAutomaton(init, dir, "init"); PrintAutomaton(bad, dir, "bad"); PrintAutomaton(tau, dir, "tau"); if (taus.Length > 1) // no point in only printing tau1 { for (int i = 0; i < taus.Length; i++) { PrintAutomaton(taus[i], dir, "tau" + (i + 1).ToString()); } } PrintAutomaton(tauInv, dir, "tau-inv"); config.Write(Path.Combine(dir, "armc.properties")); } if (config.ComputationDirection == Config.Direction.Backward) { /* reverse direction, i.e. check if tauInv*(bad) & init is empty */ this.init = bad; this.bad = init; this.tauInv = tau; this.tau = tau.Invert(); } if (!SSA <SYMBOL> .ProductIsEmpty(init, bad)) // no point in further verification { if (printAutomata) { string dir = Path.Combine(outputDir, "armc-counterexample"); Directory.CreateDirectory(dir); PrintAutomaton(init & bad, dir, "initXbad"); } throw ARMCException.InitialPropertyViolation(); } }