private static void Benchmark(List <MuFormula> list) { Log("Formula; LTS Size; Algorithm; Time"); double[,] results = new double[list.Count * 2, 13]; bool lastResult = false; foreach (var formula in list) { int num_runs = 4; for (int i = 2; i <= 13; i++) { if (i >= 11) { num_runs = 1; } var sw = Stopwatch.StartNew(); var lts = LTS.Parse("../demanding/demanding_" + i.ToString(CultureInfo.InvariantCulture) + ".aut"); Log("Read input set in {0}ms", sw.ElapsedMilliseconds); sw.Reset(); sw.Start(); for (int j = 0; j < num_runs; j++) { lastResult = NaiveSolver.Solve(formula, lts, new Environment()).Contains(lts.InitialState); } results[list.IndexOf(formula) * 2 + 0, i - 2] = (double)sw.ElapsedMilliseconds / num_runs; Log("{0}\t{1}\t{2}\t{3}\t{4}", list.IndexOf(formula) + 1, i, "Naive ", (double)sw.ElapsedMilliseconds / (double)num_runs, lastResult); sw.Reset(); sw.Start(); for (int j = 0; j < num_runs; j++) { lastResult = EmersonLei.Solve(formula, lts, new Environment()).Contains(lts.InitialState); } results[list.IndexOf(formula) * 2 + 1, i - 2] = (double)sw.ElapsedMilliseconds / num_runs; Log("{0}\t{1}\t{2}\t{3}\t{4}", list.IndexOf(formula) + 1, i, "Emerson-Lei", (double)sw.ElapsedMilliseconds / (double)num_runs, lastResult); logWriter.Flush(); lts = null; } } Log(""); Log(""); Log("Results table:"); Log("lts size\tformula1 naive\tformula1 emers\tformula2 naive\tformula2 emers\tformula3 naive\tformula3 emers\tformula4 naive\tformula4 emers"); for (int j = 0; j < results.GetLength(1); j++) { var sb = new StringBuilder(); sb.Append((j + 2).ToString()); for (int i = 0; i < results.GetLength(0); i++) { sb.AppendFormat("\t{0}", results[i, j]); } Log(sb.ToString()); } }
static LTS ChessBoard(int boardSize) { // this procedure outputs a board of size boardSize x boardSize in aldebaran format var lts = new LTS(); var board = new LTSState[boardSize, boardSize]; int stateNum = 0; var initial = new LTSState(stateNum++.ToString(), lts); lts.InitialState = initial; for (int i = 0; i < boardSize; i++) { for (int j = 0; j < boardSize; j++) { var cell = new LTSState(stateNum++.ToString(), lts); board[i, j] = cell; lts.States.Add(cell); } } lts.States.Add(initial); for (int i = 0; i < boardSize; i++) { lts.Transitions.Add(new LTSTransition(initial, board[boardSize - 1, i], "start(" + (boardSize - 1) + "," + i + ")")); if (i != boardSize - 1) // don't want 2 transitions to same init { lts.Transitions.Add(new LTSTransition(initial, board[i, boardSize - 1], "start(" + i + "," + (boardSize - 1) + ")")); } } for (int y = boardSize - 1; y >= 0; y--) { for (int x = boardSize - 1; x >= 0; x--) { var thisCell = board[x, y]; // horizontal moves for (int i = x - 1; i >= 0; i--) { lts.Transitions.Add(new LTSTransition(thisCell, string.Format("to({0},{1})", i, y), board[i, y])); } // vertical moves for (int j = y - 1; j >= 0; j--) { lts.Transitions.Add(new LTSTransition(thisCell, string.Format("to({0},{1})", x, j), board[x, j])); } // diagonal moves int k = x - 1, l = y - 1; while (k >= 0 && l >= 0) { lts.Transitions.Add(new LTSTransition(thisCell, string.Format("to({0},{1})", k, l), board[k--, l--])); } } } return(lts); }
private static LTSState GetState(string stateName, LTS lts) { LTSState state; if (lts.StatesMap.TryGetValue(stateName, out state)) return state; else { state = new LTSState(stateName, lts); lts.StatesMap[stateName] = state; lts.States.Add(state); } return state; }
public static HashSet<LTSState> LFP(PredicateTransformer tau, LTS lts, Environment env) { var Q = Tuple.Create(new HashSet<LTSState>(), lts, env); var QPrime = tau(Q); while (QPrime.Item1.Count() != Q.Item1.Count()) { Q = QPrime; QPrime = tau(QPrime); } return Q.Item1; }
public static HashSet <LTSState> GFP(PredicateTransformer tau, LTS lts, Environment env) { var Q = Tuple.Create(new HashSet <LTSState>(lts.States), lts, env); var QPrime = tau(Q); while (QPrime.Item1.Count() != Q.Item1.Count()) { Q = QPrime; QPrime = tau(QPrime); } return(Q.Item1); }
private static void OutputResult(MuFormula f, LTS lts) { Log("Formula {0}", f); Log("\t ND: {0}, AD: {1}, DAD: {2}", f.NestingDepth, f.AlternationDepth, f.DependentAlternationDepth); var naiveSol = NaiveSolver.Solve(f, lts, new Environment()); Log("\tNAIVE: {0}", naiveSol.Contains(lts.InitialState)); var emersonLeiSol = EmersonLei.Solve(f, lts, new Environment()); Log("\tEMLEI: {0}", emersonLeiSol.Contains(lts.InitialState)); }
private static void Init(IEnumerable <Variable> variables, LTS lts, Environment env) { foreach (var v in variables) { if (v.Binder is Mu) { env[v] = new HashSet <LTSState>(); } else if (v.Binder is Nu) { env[v] = lts.States; } } }
private static LTSState GetState(string stateName, LTS lts) { LTSState state; if (lts.StatesMap.TryGetValue(stateName, out state)) { return(state); } else { state = new LTSState(stateName, lts); lts.StatesMap[stateName] = state; lts.States.Add(state); } return(state); }
public static LTS Parse(string file) { // parse aldebran format var ret = new LTS(); var sr = new StreamReader(file, Encoding.Default); var lineRE = new Regex(@"\((\w+)\s*,\s*""([^\""]+?)""\s*,\s*(\w+)\s*\)"); string initial = string.Empty; while (!sr.EndOfStream) { var line = sr.ReadLine(); if (line.StartsWith("des")) { var m = Regex.Match(line, @"des\s*\((\w+?),(\w+?),(\w+?)\)"); if (m.Success) { initial = m.Groups[1].Captures[0].Value; } continue; } var match = lineRE.Match(line); if (match.Success) { string start = match.Groups[1].Captures[0].Value; string label = match.Groups[2].Captures[0].Value; string end = match.Groups[3].Captures[0].Value; LTSState startState = GetState(start, ret); LTSState endState = GetState(end, ret); LTSTransition trans = new LTSTransition(startState, label, endState); ret.Actions.Add(label); ret.Transitions.Add(trans); startState.AddOutTransition(trans); //endState.AddInTransition(trans); } else { int i = 0; } } ret.InitialState = GetState(initial, ret); return(ret); }
static LTS ChessBoard(int boardSize) { // this procedure outputs a board of size boardSize x boardSize in aldebaran format var lts = new LTS(); var board = new LTSState[boardSize, boardSize]; int stateNum = 0; var initial = new LTSState(stateNum++.ToString(), lts); lts.InitialState = initial; for (int i = 0; i < boardSize; i++) { for (int j = 0; j < boardSize; j++) { var cell = new LTSState(stateNum++.ToString(), lts); board[i, j] = cell; lts.States.Add(cell); } } lts.States.Add(initial); for (int i = 0; i < boardSize; i++) { lts.Transitions.Add(new LTSTransition(initial, board[boardSize - 1, i], "start(" + (boardSize - 1) + "," + i + ")")); if (i != boardSize - 1) // don't want 2 transitions to same init lts.Transitions.Add(new LTSTransition(initial, board[i, boardSize - 1], "start(" + i + "," + (boardSize - 1) + ")")); } for (int y = boardSize - 1; y >= 0; y--) { for (int x = boardSize - 1; x >= 0; x--) { var thisCell = board[x, y]; // horizontal moves for (int i = x - 1; i >= 0; i--) lts.Transitions.Add(new LTSTransition(thisCell, string.Format("to({0},{1})", i, y), board[i, y])); // vertical moves for (int j = y - 1; j >= 0; j--) lts.Transitions.Add(new LTSTransition(thisCell, string.Format("to({0},{1})", x, j), board[x, j])); // diagonal moves int k = x - 1, l = y - 1; while (k >= 0 && l >= 0) lts.Transitions.Add(new LTSTransition(thisCell, string.Format("to({0},{1})", k, l), board[k--, l--])); } } return lts; }
public static LTS Parse(string file) { // parse aldebran format var ret = new LTS(); var sr = new StreamReader(file, Encoding.Default); var lineRE = new Regex(@"\((\w+)\s*,\s*""([^\""]+?)""\s*,\s*(\w+)\s*\)"); string initial = string.Empty; while (!sr.EndOfStream) { var line = sr.ReadLine(); if (line.StartsWith("des")) { var m = Regex.Match(line, @"des\s*\((\w+?),(\w+?),(\w+?)\)"); if (m.Success) { initial = m.Groups[1].Captures[0].Value; } continue; } var match = lineRE.Match(line); if (match.Success) { string start = match.Groups[1].Captures[0].Value; string label = match.Groups[2].Captures[0].Value; string end = match.Groups[3].Captures[0].Value; LTSState startState = GetState(start, ret); LTSState endState = GetState(end, ret); LTSTransition trans = new LTSTransition(startState, label, endState); ret.Actions.Add(label); ret.Transitions.Add(trans); startState.AddOutTransition(trans); //endState.AddInTransition(trans); } else { int i = 0; } } ret.InitialState = GetState(initial, ret); return ret; }
static void Main(string[] args) { var p = new MuCalculusParser(); p.Setup(); bool b = p.Parse(new StringReader("nu X.((mu Y . [b]Y) && nu Z.((<b> X) && (<a>(Z && <a> X))))\r\n")); string ltsPath = args[0]; string formulasPath = args[1]; Log("LTS: {0}", ltsPath); var parser = new MuCalculusParser(); parser.Setup(); var fileStream = new FileStream(formulasPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); bool parseResult = parser.Parse(new StreamReader(fileStream, Encoding.Default)); fileStream.Close(); if (!parseResult) { Log("Failed to parse!"); } LTS lts = LTS.Parse(ltsPath); foreach (MuFormula f in parser.formulas) { Log("----------------------------------"); OutputResult(f, lts); } Log(); Log(); logWriter.Flush(); logWriter.Close(); Console.ReadKey(); }
public static HashSet <LTSState> Solve(MuFormula formula, LTS lts, Environment env) { if (formula is Proposition) { var prop = formula as Proposition; return(bool.Parse(prop.Value) ? lts.States : new HashSet <LTSState>()); } else if (formula is Variable) { return(env.GetVariable(formula as Variable)); } else if (formula is Negation) { var neg = formula as Negation; return(new HashSet <LTSState>(lts.States.Except( Solve(neg.Formula, lts, env)))); } else if (formula is Conjunction) { var conj = formula as Conjunction; var leftStates = Solve(conj.Left, lts, env); var rightStates = Solve(conj.Right, lts, env); return(new HashSet <LTSState>(leftStates.Intersect(rightStates))); } else if (formula is Disjunction) { var disj = formula as Disjunction; var leftStates = Solve(disj.Left, lts, env); var rightStates = Solve(disj.Right, lts, env); return(new HashSet <LTSState>(leftStates.Union(rightStates))); } else if (formula is Box) { var box = formula as Box; // box a f = { s | forall t. s -a-> t ==> t in [[f]]e } // i.e. the set of states for which all a-transitions go to a state in which f holds var fe = Solve(box.Formula, lts, env); return(new HashSet <LTSState>(lts.States.Where( // states where, for all outtransitions with action a, the Formula holds in the direct successor state => state.GetOutTransitions(box.RegularFormula).All(tr => fe.Contains(tr.Right)) ))); } else if (formula is Diamond) { var diamond = formula as Diamond; var shorthand = new Negation( // <a>f == [a](not f) new Box(diamond.RegularFormula, new Negation(diamond.Formula)) ); return(Solve(shorthand, lts, env)); } else if (formula is Mu) { var mu = formula as Mu; env[mu.Variable] = new HashSet <LTSState>(); return(FixedPoint.LFP(delegate(Tuple <HashSet <LTSState>, LTS, Environment> tuple) { // repeats tau: X := solve(f) var X = tuple.Item1; X = Solve(mu.Formula, lts, env); env[mu.Variable] = X; return Tuple.Create(X, lts, env); }, lts, env)); } else if (formula is Nu) { var nu = formula as Nu; env[nu.Variable] = lts.States; return(FixedPoint.GFP(delegate(Tuple <HashSet <LTSState>, LTS, Environment> tuple) { // repeats tau: X := solve(f) var X = tuple.Item1; X = Solve(nu.Formula, lts, env); env[nu.Variable] = X; return Tuple.Create(X, lts, env); }, lts, env)); } throw new InvalidDataException("not a valid formula in our grammar"); }
public LTSState(string name, LTS lts) { Name = name; LTS = lts; }
public static HashSet <LTSState> Solve(MuFormula formula, LTS lts, Environment env, bool init = true) { if (init) { var allVariables = new List <Variable>(); if (formula is Variable) { allVariables.Add((Variable)formula); } allVariables.AddRange(formula.AllSubFormulas.OfType <Variable>()); allVariables.AddRange(formula.AllSubFormulas.OfType <Mu>().Select(mu => mu.Variable)); allVariables.AddRange(formula.AllSubFormulas.OfType <Nu>().Select(nu => nu.Variable)); Init(allVariables.Distinct(), lts, env); } if (formula is Proposition) { var prop = formula as Proposition; return(bool.Parse(prop.Value) ? lts.States : new HashSet <LTSState>()); } else if (formula is Variable) { return(env.GetVariable(formula as Variable)); } else if (formula is Negation) { var neg = formula as Negation; return(new HashSet <LTSState>(lts.States.Except( Solve(neg.Formula, lts, env, false)))); } else if (formula is Conjunction) { var conj = formula as Conjunction; var leftStates = Solve(conj.Left, lts, env, false); var rightStates = Solve(conj.Right, lts, env, false); return(new HashSet <LTSState>(leftStates.Intersect(rightStates))); } else if (formula is Disjunction) { var disj = formula as Disjunction; var leftStates = Solve(disj.Left, lts, env, false); var rightStates = Solve(disj.Right, lts, env, false); return(new HashSet <LTSState>(leftStates.Union(rightStates))); } else if (formula is Box) { var box = formula as Box; // box a f = { s | forall t. s -a-> t ==> t in [[f]]e } // i.e. the set of states for which all a-transitions go to a state in which f holds var fe = Solve(box.Formula, lts, env, false); var hashSet = new HashSet <LTSState>(); foreach (var state in lts.States) { var outTransitions = state.GetOutTransitions(box.RegularFormula); if (outTransitions.All(tr => fe.Contains(tr.Right))) { hashSet.Add(state); } } return(hashSet); } else if (formula is Diamond) { var diamond = formula as Diamond; var shorthand = new Negation( // <a>f == [a](not f) new Box(diamond.RegularFormula, new Negation(diamond.Formula)) ); return(Solve(shorthand, lts, env, false)); } else if (formula is Mu) { var mu = formula as Mu; if (mu.Parent is Nu) { // surrounding binder is nu // reset open subformulae of form mu Xk.g set env[k]=false foreach (var innerMu in formula.AllSubFormulas.OfType <Mu>().Where(m => m.FreeVariables.Count > 0)) { env[innerMu.Variable] = new HashSet <LTSState>(); } } HashSet <LTSState> Xold; do { Xold = env.GetVariable(mu.Variable); env[mu.Variable] = Solve(mu.Formula, lts, env, false); } while (Xold.Count != env[mu.Variable].Count); return(env[mu.Variable]); } else if (formula is Nu) { var nu = formula as Nu; if (nu.Parent is Mu) { // surrounding binder is mu // reset open subformulae of form nu Xk.g set env[k]=true foreach (var innerNu in formula.AllSubFormulas.OfType <Nu>().Where(m => m.FreeVariables.Count > 0)) { env[innerNu.Variable] = lts.States; } } HashSet <LTSState> Xold; do { Xold = env.GetVariable(nu.Variable); env[nu.Variable] = Solve(nu.Formula, lts, env, false); } while (Xold.Count != env[nu.Variable].Count); return(env[nu.Variable]); } throw new InvalidDataException("formula not valid in our grammar"); }
private static void Init(IEnumerable<Variable> variables, LTS lts, Environment env) { foreach (var v in variables) { if (v.Binder is Mu) env[v] = new HashSet<LTSState>(); else if (v.Binder is Nu) env[v] = lts.States; } }
public static HashSet<LTSState> Solve(MuFormula formula, LTS lts, Environment env, bool init = true) { if (init) { var allVariables = new List<Variable>(); if (formula is Variable) allVariables.Add((Variable)formula); allVariables.AddRange(formula.AllSubFormulas.OfType<Variable>()); allVariables.AddRange(formula.AllSubFormulas.OfType<Mu>().Select(mu => mu.Variable)); allVariables.AddRange(formula.AllSubFormulas.OfType<Nu>().Select(nu => nu.Variable)); Init(allVariables.Distinct(), lts, env); } if (formula is Proposition) { var prop = formula as Proposition; return bool.Parse(prop.Value) ? lts.States : new HashSet<LTSState>(); } else if (formula is Variable) { return env.GetVariable(formula as Variable); } else if (formula is Negation) { var neg = formula as Negation; return new HashSet<LTSState>(lts.States.Except( Solve(neg.Formula, lts, env, false))); } else if (formula is Conjunction) { var conj = formula as Conjunction; var leftStates = Solve(conj.Left, lts, env, false); var rightStates = Solve(conj.Right, lts, env, false); return new HashSet<LTSState>(leftStates.Intersect(rightStates)); } else if (formula is Disjunction) { var disj = formula as Disjunction; var leftStates = Solve(disj.Left, lts, env, false); var rightStates = Solve(disj.Right, lts, env, false); return new HashSet<LTSState>(leftStates.Union(rightStates)); } else if (formula is Box) { var box = formula as Box; // box a f = { s | forall t. s -a-> t ==> t in [[f]]e } // i.e. the set of states for which all a-transitions go to a state in which f holds var fe = Solve(box.Formula, lts, env, false); var hashSet = new HashSet<LTSState>(); foreach (var state in lts.States) { var outTransitions = state.GetOutTransitions(box.RegularFormula); if (outTransitions.All(tr => fe.Contains(tr.Right))) hashSet.Add(state); } return hashSet; } else if (formula is Diamond) { var diamond = formula as Diamond; var shorthand = new Negation( // <a>f == [a](not f) new Box(diamond.RegularFormula, new Negation(diamond.Formula)) ); return Solve(shorthand, lts, env, false); } else if (formula is Mu) { var mu = formula as Mu; if (mu.Parent is Nu) { // surrounding binder is nu // reset open subformulae of form mu Xk.g set env[k]=false foreach (var innerMu in formula.AllSubFormulas.OfType<Mu>().Where(m => m.FreeVariables.Count > 0)) env[innerMu.Variable] = new HashSet<LTSState>(); } HashSet<LTSState> Xold; do { Xold = env.GetVariable(mu.Variable); env[mu.Variable] = Solve(mu.Formula, lts, env, false); } while (Xold.Count != env[mu.Variable].Count); return env[mu.Variable]; } else if (formula is Nu) { var nu = formula as Nu; if (nu.Parent is Mu) { // surrounding binder is mu // reset open subformulae of form nu Xk.g set env[k]=true foreach (var innerNu in formula.AllSubFormulas.OfType<Nu>().Where(m => m.FreeVariables.Count > 0)) env[innerNu.Variable] = lts.States; } HashSet<LTSState> Xold; do { Xold = env.GetVariable(nu.Variable); env[nu.Variable] = Solve(nu.Formula, lts, env, false); } while (Xold.Count != env[nu.Variable].Count); return env[nu.Variable]; } throw new InvalidDataException("formula not valid in our grammar"); }
public static HashSet<LTSState> Solve(MuFormula formula, LTS lts, Environment env) { if (formula is Proposition) { var prop = formula as Proposition; return bool.Parse(prop.Value) ? lts.States : new HashSet<LTSState>(); } else if (formula is Variable) { return env.GetVariable(formula as Variable); } else if (formula is Negation) { var neg = formula as Negation; return new HashSet<LTSState>(lts.States.Except( Solve(neg.Formula, lts, env))); } else if (formula is Conjunction) { var conj = formula as Conjunction; var leftStates = Solve(conj.Left, lts, env); var rightStates = Solve(conj.Right, lts, env); return new HashSet<LTSState>(leftStates.Intersect(rightStates)); } else if (formula is Disjunction) { var disj = formula as Disjunction; var leftStates = Solve(disj.Left, lts, env); var rightStates = Solve(disj.Right, lts, env); return new HashSet<LTSState>(leftStates.Union(rightStates)); } else if (formula is Box) { var box = formula as Box; // box a f = { s | forall t. s -a-> t ==> t in [[f]]e } // i.e. the set of states for which all a-transitions go to a state in which f holds var fe = Solve(box.Formula, lts, env); return new HashSet<LTSState>(lts.States.Where( // states where, for all outtransitions with action a, the Formula holds in the direct successor state => state.GetOutTransitions(box.RegularFormula).All(tr => fe.Contains(tr.Right)) )); } else if (formula is Diamond) { var diamond = formula as Diamond; var shorthand = new Negation( // <a>f == [a](not f) new Box(diamond.RegularFormula, new Negation(diamond.Formula)) ); return Solve(shorthand, lts, env); } else if (formula is Mu) { var mu = formula as Mu; env[mu.Variable] = new HashSet<LTSState>(); return FixedPoint.LFP(delegate(Tuple<HashSet<LTSState>, LTS, Environment> tuple) { // repeats tau: X := solve(f) var X = tuple.Item1; X = Solve(mu.Formula, lts, env); env[mu.Variable] = X; return Tuple.Create(X, lts, env); }, lts, env); } else if (formula is Nu) { var nu = formula as Nu; env[nu.Variable] = lts.States; return FixedPoint.GFP(delegate(Tuple<HashSet<LTSState>, LTS, Environment> tuple) { // repeats tau: X := solve(f) var X = tuple.Item1; X = Solve(nu.Formula, lts, env); env[nu.Variable] = X; return Tuple.Create(X, lts, env); }, lts, env); } throw new InvalidDataException("not a valid formula in our grammar"); }