/// <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(); } }
/// <summary> /// Constructs configuration from file. /// </summary> /// <param name="fileName">File path.</param> public Config(string fileName) { PropertyInfo[] properties = this.GetType().GetProperties(); var regex = new Regex(@"^(\w+)\s*=\s*([^\s]*)$"); var propFound = new Dictionary <string, bool>(properties.Length); foreach (var prop in properties) { propFound[PropertyToFile(prop.Name)] = false; } foreach (string line in File.ReadLines(fileName)) { if (line == "" || line[0] == '#') { continue; } Match match = regex.Match(line); if (!match.Success) { throw ConfigException.BadFileFormat(); } string name = match.Groups[1].Value; string value = match.Groups[2].Value; if (!propFound.ContainsKey(name)) { throw ConfigException.UnknownProperty(name); } if (propFound[name]) { throw ConfigException.DuplicateProperty(name); } propFound[name] = true; PropertyInfo property = Array.Find(properties, prop => prop.Name == PropertyFromFile(name)); Type type = property.PropertyType; if (type == typeof(string)) { property.SetValue(this, value); } else if (type == typeof(string[])) { property.SetValue(this, value.Split(Path.PathSeparator)); } else if (type == typeof(bool)) { if (value == "YES") { property.SetValue(this, true); } else if (value == "NO") { property.SetValue(this, false); } else { throw ConfigException.BadPropertyValue(name); } } else if (type == typeof(TimeSpan)) { try { property.SetValue(this, TimeSpan.Parse(value)); } catch (FormatException) { throw ConfigException.BadPropertyValue(name); } } else { Type utype = Nullable.GetUnderlyingType(type); if (utype != null) { if (value == "") { property.SetValue(this, null); continue; } type = utype; } if (!Enum.GetNames(type).Contains(value)) { throw ConfigException.BadPropertyValue(name); } property.SetValue(this, Enum.Parse(type, value)); } } foreach (KeyValuePair <string, bool> pair in propFound) { if (!pair.Value) { throw ConfigException.MissingProperty(pair.Key); } } if (PredicateLanguages == FiniteLengthLanguages) { throw ConfigException.AbstractionNotChosen(); } }