static MuFormula RewriteBoxDia(MuFormula form) { // We extended our grammar from the assignment by allowing regular formulas instead of single-letter actions. // Here, we rewrite such extended formulas to their more primitive versions for which we impemented evaluators. if (form is Diamond) { var dia = form as Diamond; if (dia.RegularFormula.Multiplier == "+") { // <R+>f = <R><R*>f var rf2 = dia.RegularFormula.Clone(); rf2.Multiplier = "*"; dia.RegularFormula.Multiplier = ""; dia.Formula = new Diamond(dia.RegularFormula, new Diamond(rf2, dia.Formula)); } else if (dia.RegularFormula.Multiplier == "*") { // <R*>f = mu X . (<R> X || f) var var = new Variable(GetFreeVar()); dia.RegularFormula.Multiplier = ""; return Rewrite(new Mu(var, new Disjunction(new Diamond(dia.RegularFormula, var), dia.Formula))); } dia.Formula = Rewrite(dia.Formula); } else if (form is Box) { var box = form as Box; if (box.RegularFormula.Multiplier == "+") { // [R+]f = [R][R*]f var rf2 = box.RegularFormula.Clone(); rf2.Multiplier = "*"; box.RegularFormula.Multiplier = ""; return new Box(box.RegularFormula, new Box(rf2, box.Formula)); } else if (box.RegularFormula.Multiplier == "*") { // [R*]f = nu X . ([R] X && f) var var = new Variable(GetFreeVar()); box.RegularFormula.Multiplier = ""; return Rewrite(new Nu(var, new Disjunction(new Box(box.RegularFormula, var), box.Formula))); } box.Formula = Rewrite(box.Formula); } // we also need to perform this on all subformulas else if (form is Disjunction) form = new Disjunction(Rewrite(((Disjunction)form).Left), Rewrite(((Disjunction)form).Right)); else if (form is Conjunction) form = new Conjunction(Rewrite(((Conjunction)form).Left), Rewrite(((Conjunction)form).Right)); else if (form is Mu) form = new Mu(((Mu)form).Variable, Rewrite(((Mu)form).Formula)); else if (form is Nu) form = new Nu(((Nu)form).Variable, Rewrite(((Nu)form).Formula)); else if (form is Negation) form = new Negation(Rewrite(((Negation)form).Formula)); return form; }
private object CreateNewObject(GOLD.Reduction r) { object result = null; switch ((ProductionIndex)r.Parent.TableIndex()) { case ProductionIndex.Nl_Newline: // <nl> ::= NewLine <nl> break; case ProductionIndex.Nl_Newline2: // <nl> ::= NewLine break; case ProductionIndex.Regform_Pipepipe: // <regForm> ::= <regForm> '||' <regFormSeq> result = new UnionFormula((RegularFormula)r[0].Data, (RegularFormula)r[2].Data); break; case ProductionIndex.Regform: // <regForm> ::= <regFormSeq> result = r[0].Data; break; case ProductionIndex.Regformseq_Dot: // <regFormSeq> ::= <regFormSeq> '.' <regFormValue> result = new SequenceFormula((RegularFormula)r[0].Data, (RegularFormula)r[2].Data); break; case ProductionIndex.Regformseq: // <regFormSeq> ::= <regFormValue> result = r[0].Data; break; case ProductionIndex.Regformvalue_Identifier: // <regFormValue> ::= Identifier <Multiplier> result = new SingleAction((string)r[0].Data, (string)r[1].Data); break; case ProductionIndex.Regformvalue_Not: // <regFormValue> ::= not <regForm> result = new NegateAction((RegularFormula)r[1].Data); break; case ProductionIndex.Regformvalue_Lparen_Rparen: // <regFormValue> ::= '(' <regForm> ')' <Multiplier> if ((string)r[3].Data != "") return new NestedFormula((RegularFormula)r[1].Data, (string)r[3].Data); else // small optimization result = r[1].Data; break; case ProductionIndex.Multiplier_Plus: // <Multiplier> ::= '+' result = "+"; break; case ProductionIndex.Multiplier_Times: // <Multiplier> ::= '*' result = "*"; break; case ProductionIndex.Multiplier: // <Multiplier> ::= result = ""; break; case ProductionIndex.Muform_Identifier: // <muForm> ::= Identifier result = new Proposition((string)r[0].Data); break; case ProductionIndex.Muform_Variable: // <muForm> ::= Variable result = new Variable((string)r[0].Data); break; case ProductionIndex.Muform_Lparen_Pipepipe_Rparen: // <muForm> ::= '(' <muForm> '||' <muForm> ')' result = new Disjunction((MuFormula)r[1].Data, (MuFormula)r[3].Data); break; case ProductionIndex.Muform_Lparen_Ampamp_Rparen: // <muForm> ::= '(' <muForm> '&&' <muForm> ')' result = new Conjunction((MuFormula)r[1].Data, (MuFormula)r[3].Data); break; case ProductionIndex.Muform_Lt_Gt: // <muForm> ::= '<' <regForm> '>' <muForm> result = new Diamond((RegularFormula)r[1].Data, (MuFormula)r[3].Data); break; case ProductionIndex.Muform_Lbracket_Rbracket: // <muForm> ::= '[' <regForm> ']' <muForm> result = new Box((RegularFormula)r[1].Data, (MuFormula)r[3].Data); break; case ProductionIndex.Muform_Mu_Variable_Dot: // <muForm> ::= mu Variable '.' <muForm> result = new Mu(new Variable((string)r[1].Data), (MuFormula)r[3].Data); break; case ProductionIndex.Muform_Nu_Variable_Dot: // <muForm> ::= nu Variable '.' <muForm> result = new Nu(new Variable((string)r[1].Data), (MuFormula)r[3].Data); break; case ProductionIndex.Muform_Not: // <muForm> ::= not <muForm> result = new Negation((MuFormula)r[1].Data); break; case ProductionIndex.Muform_Lparen_Rparen: result = r[1].Data as MuFormula; break; case ProductionIndex.Line_Commentl: // <Line> ::= CommentL <nl> break; case ProductionIndex.Line: // <Line> ::= <muForm> <nl> var form = (MuFormula)r[0].Data; FormulaRewriter.ResetFreeVars(); form = FormulaRewriter.Rewrite(form); form.SetParents(null /* root has no parent */); formulas.Add(form); break; case ProductionIndex.Line2: // <Line> ::= <nl> break; case ProductionIndex.Lines: // <Lines> ::= <Line> <Lines> break; case ProductionIndex.Lines2: // <Lines> ::= break; } //switch return result; }
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, 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"); }