private LinkedList <ITlaState> VerifyWithIntersection(TlaAutomaton ltl) { var automaton = this.Intersect(_modelAutomaton, ltl); automaton.Optimize(); PathItem cycle = null; var path = automaton.InitialStates.Select(initState => this.RunAutomatonFrom(initState, step => { //if (step.Prev.IsAny(step.State)) // return true; if (!step.State.IsAccepting) { return(false); } cycle = this.RunAutomatonFrom(step.State, cycleStep => step.IsAny(cycleStep.State)); return(cycle != null); })).FirstOrDefault(l => l != null); //var r = new DoubeDfs(automaton).emptiness(); //Console.WriteLine("DFS: {0}", r ? "found path" : "no path"); //if ((path != null) == r) // Console.WriteLine("OK"); //else // Console.WriteLine("FAIL"); return(this.MakeResult(automaton, path, cycle)); }
public static TlaAutomaton TranslateToTlaAutomaton(this automaton root, bool useTransitionConditions, AutomatonParsingContext ctx) { var automaton = new TlaAutomaton(); foreach (var state in root.states) { var name = state.stateName.identifier.@string; automaton.CreateState(name, name.EndsWith("_init"), name.StartsWith("accept_")); } foreach (var state in root.states) { foreach (var target in state.transitions) { var condition = target.condition.Translate(useTransitionConditions, ctx); automaton.CreateTransition(state.stateName.identifier.@string, target.stateName.identifier.@string, condition); } if (state.skip != null) { automaton.CreateTransition( state.stateName.identifier.@string, state.stateName.identifier.@string, useTransitionConditions ? new TlaTransitionConditionFormula(new Model.TransitionConditionExpr.ConstExpr(true)) : (TlaFormula) new TlaExprFormula(new TlaExpr.Const(true)) ); } } return(automaton); }
public static XmlGraph ToXmlGraph(this TlaAutomaton automaton) { var xg = new XmlGraph(); foreach (var state in automaton.AllStates) { string name = string.Empty; if (state.IsInitial) { name += "Initial" + Environment.NewLine; } name += state.Name; if (state.IsAccepting) { name += Environment.NewLine + "Accepting"; } xg.CreateNode(state.Name).Text = name; } foreach (var item in automaton.AllTransitions) { xg[item.FromState.Name].ConnectTo(xg[item.ToState.Name]).Text = item.Condition == null ? "<NULL>" : item.Condition.ToString(); } return(xg); }
private void AddLoopStateToFinalStates(TlaAutomaton a) { foreach (var st in a.AcceptingStates) { if (!st.Name.Contains("|") && st.Outgoings.Count == 0) { a.CreateTransition(st.Id, st.Id, new TlaTransitionConditionFormula(new TransitionConditionExpr.ConstExpr(true))); } } }
public AutomatonVerifier(TlaAutomaton sm) { if (sm.AllTransitions.Any(t => !t.Condition.IsConjunction())) { throw new ArgumentException(); } // loops on original model? this.AddLoopStateToFinalStates(sm); _modelAutomaton = sm; }
private LinkedList <ITlaState> VerifyWithTraverse(TlaAutomaton ltl) { var limit = _modelAutomaton.AllStates.Count * ltl.AllStates.Count; PathItem statement = null; var path = _modelAutomaton.InitialStates.Select(initState => this.RunAutomatonTraversingFrom(initState, step => { if (!step.State.Name.Contains('|')) { statement = ltl.InitialStates.Select(checkerInitState => this.RunChecker(step.State, checkerInitState, limit)).FirstOrDefault(p => p != null); return(statement != null); } return(false); })).FirstOrDefault(p => p != null); return(this.MakeResult(_modelAutomaton, path, statement)); }
void LoadModelAutomaton(string fileName) { try { _model = _modelLoader.LoadFromXml(fileName); _verifier = new AutomatonVerifier(_model); Console.WriteLine("Automaton loaded."); } catch (Exception ex) { Console.WriteLine(ex.Message); } if (_model == null) { Console.WriteLine("Can't create automaton"); } }
private TlaAutomaton Intersect(TlaAutomaton sm, TlaAutomaton ltl) { var states = Enumerable.Range(0, 3).SelectMany(n => sm.AllStates.SelectMany(modelState => ltl.AllStates.Select(ltlState => new { name = string.Format("{0}x{1}x{2}", modelState.Id, ltlState.Id, n), tag = modelState.Name }))).ToArray(); var transitions = Enumerable.Range(0, 3).SelectMany( x => sm.AllTransitions.SelectMany(mt => ltl.AllTransitions.Select(ft => new { modelTransition = mt, ltlTransition = ft })) .Where(tt => TransitionConditionsIntersects(tt.modelTransition.FromState, tt.modelTransition.Condition, tt.ltlTransition.Condition)) .Select(tt => new { from = string.Format("{0}x{1}x{2}", tt.modelTransition.FromState.Id, tt.ltlTransition.FromState.Id, x), to = string.Format("{0}x{1}x{2}", tt.modelTransition.ToState.Id, tt.ltlTransition.ToState.Id, ComputeTransitionY(tt.modelTransition.ToState, tt.ltlTransition.ToState, x)), modelSymbol = tt.modelTransition.Condition, ltlSymbol = tt.ltlTransition.Condition, condition = new TlaTransitionConditionFormula(new TransitionConditionExpr.BinaryExpr( TransitionConditionBinaryExprKind.BoolAnd, new TransitionConditionExpr.VarExpr(tt.modelTransition.FromState.Name), (tt.modelTransition.Condition as TlaTransitionConditionFormula).Expression )) }) ).ToArray(); var initialStates = new SortedSet <string>(sm.InitialStates.SelectMany(modelState => ltl.InitialStates.Select(ltlState => string.Format("{0}x{1}x0", modelState.Id, ltlState.Id)))); var acceptingStates = new SortedSet <string>(sm.AllStates.SelectMany(modelState => ltl.AllStates.Select(ltlState => string.Format("{0}x{1}x2", modelState.Id, ltlState.Id)))); var result = new TlaAutomaton(); foreach (var state in states) { result.CreateState(state.name, initialStates.Contains(state.name), acceptingStates.Contains(state.name)).Tag = state.tag; } foreach (var t in transitions) { result.CreateTransition(t.from, t.to, t.condition); } return(result); }
void Verify(string ltl) { _ltlFormula = _ltlParser.Parse(ltl); if (_verifier != null) { var result = _verifier.Verify(_ltlFormula, true); if (result != null) { Console.WriteLine("Specification {0} is FALSE", ltl); Console.WriteLine("\tsee LTL counterexample: "); foreach (var counterexample in result) { if (counterexample.Tag != null) { if (!counterexample.Tag.ToString().Contains('|')) { Console.WriteLine("\t\t" + counterexample.Tag); } } else { if (!counterexample.Name.ToString().Contains('|')) { Console.WriteLine("\t\t" + counterexample.Name); } } } } else { Console.WriteLine("Specification {0} is TRUE", ltl); } } else { Console.WriteLine("Verifier is not initialized with model."); } }
LinkedList <ITlaState> MakeResult(TlaAutomaton automaton, PathItem path, PathItem cycle) { var xg = automaton.ToXmlGraph(); this.LastVerificationGraphInfo = xg; if (path != null) { for (var item = cycle; item != null; item = item.Prev) { xg[item.State.Name].Background = "Blue"; if (item.FromTransition != null) { xg[item.FromTransition.FromState.Name].GetConnectionTargets().First(l => l.Target.Id == item.FromTransition.ToState.Name).Color = "Blue"; } } var list = new LinkedList <ITlaState>(); for (var item = path; item != null; item = item.Prev) { xg[item.State.Name].Background = "Green"; list.AddFirst(item.State); if (item.FromTransition != null) { xg[item.FromTransition.FromState.Name].GetConnectionTargets().First(l => l.Target.Id == item.FromTransition.ToState.Name).Color = "Green"; } } return(list); } else { return(null); } }
public DoubeDfs(TlaAutomaton automaton) { _automaton = automaton; }
public LinkedList <ITlaState> Verify(TlaAutomaton ltl, bool intersect = true) { // this.AddLoopStateToFinalStates(ltl); return(intersect ? VerifyWithIntersection(ltl) : VerifyWithTraverse(ltl)); }
public static void SaveAsDgmlGraph(this TlaAutomaton automaton, string fileName) { automaton.ToXmlGraph().MakeXmlDocument().Save(fileName); }