/* Generate the transition relation R */ private FormulaNode GenTransition(SymbolicState from, SymbolicState to) { List <FormulaNode> terms = new List <FormulaNode>(); foreach (var e in elementary) { if (e.GetLogicOperator() != LogicOperator.EX) { continue; } // if e = EX(g), generate the term "e(from) | ~g(to)" FormulaNode body = e[0]; // the formula inside the EX FormulaNode notBody = CTLUtils.nnfNegate(body); FormulaNode left = from.ValueOf(e); FormulaNode right = to.ValueOf(notBody); terms.Add(new FormulaNode(LogicOperator.OR, left, right)); } return(JoinTerms(LogicOperator.AND, terms)); }
/* Build a propositional formula representing the value of the given CTL * formula in this state */ public FormulaNode ValueOf(FormulaNode formula) { FormulaNode result, er; switch (formula.GetLogicOperator()) { case LogicOperator.VAR: case LogicOperator.EX: // literals and EX(...) formulas are considered positive elementary, // and so should correspond directly to a propositional variable if (formula.GetLogicOperator() == LogicOperator.VAR && formula.GetName() == FormulaNode.TRUE_LITERAL) { return(new FormulaNode(FormulaNode.TRUE_LITERAL)); } return(new FormulaNode(elementaryNames[formula])); case LogicOperator.AX: FormulaNode notBody = CTLUtils.nnfNegate(formula[0]); FormulaNode ex = new FormulaNode(LogicOperator.EX, notBody, null); FormulaNode exValue = ValueOf(ex); return(new FormulaNode(LogicOperator.NOT, exValue, null)); case LogicOperator.EU: result = ValueOf(new FormulaNode(LogicOperator.EX, formula, null)); result = new FormulaNode(LogicOperator.AND, ValueOf(formula[0]), result); result = new FormulaNode(LogicOperator.OR, ValueOf(formula[1]), result); return(result); case LogicOperator.AU: er = new FormulaNode(LogicOperator.ER, CTLUtils.nnfNegate(formula[0]), CTLUtils.nnfNegate(formula[1])); result = ValueOf(new FormulaNode(LogicOperator.EX, er, null)); result = new FormulaNode(LogicOperator.NOT, result, null); result = new FormulaNode(LogicOperator.AND, ValueOf(formula[0]), result); result = new FormulaNode(LogicOperator.OR, ValueOf(formula[1]), result); return(result); case LogicOperator.ER: result = ValueOf(new FormulaNode(LogicOperator.EX, formula, null)); result = new FormulaNode(LogicOperator.OR, ValueOf(formula[0]), result); result = new FormulaNode(LogicOperator.AND, ValueOf(formula[1]), result); return(result); case LogicOperator.AR: er = new FormulaNode(LogicOperator.EU, CTLUtils.nnfNegate(formula[0]), CTLUtils.nnfNegate(formula[1])); result = ValueOf(new FormulaNode(LogicOperator.EX, er, null)); result = new FormulaNode(LogicOperator.NOT, result, null); result = new FormulaNode(LogicOperator.OR, ValueOf(formula[0]), result); result = new FormulaNode(LogicOperator.AND, ValueOf(formula[1]), result); return(result); case LogicOperator.AND: case LogicOperator.OR: return(new FormulaNode(formula.GetLogicOperator(), ValueOf(formula[0]), ValueOf(formula[1]))); case LogicOperator.NOT: FormulaNode bodyVar; if (formula[0].GetLogicOperator() == LogicOperator.VAR && formula[0].GetName() == FormulaNode.TRUE_LITERAL) { bodyVar = new FormulaNode(FormulaNode.TRUE_LITERAL); } else if (!elementaryNames.ContainsKey(formula[0])) { throw new Exception("Argument to SymbolicState.valueOf must be contained in the closure, and in NNF form."); } else { bodyVar = new FormulaNode(elementaryNames[formula[0]]); } return(new FormulaNode(LogicOperator.NOT, bodyVar, null)); default: throw new NotImplementedException(); } }
public CTLSatisfiabilityChecker(FormulaNode formula) { normalized = formula.ImplementComplexOperators().NNF(); elementary = CTLUtils.positiveElementary(normalized); }