/* Generates a formula representing the fact that for <state> either * the eventuality is not promised or that if it is, then there * exists a fragment of <stateSet> rooted at <state> such that * all the frontier nodes satisfy the eventuallity */ private FormulaNode GenA(FormulaNode stateSet, SymbolicState state) { List <FormulaNode> terms = new List <FormulaNode>(); foreach (var e in elementary) { if (e.GetLogicOperator() != LogicOperator.EX) { continue; } if (e[0].GetLogicOperator() != LogicOperator.ER) { continue; } FormulaNode frag = ComputeAUFragment(e, stateSet, state); FormulaNode promised = state.ValueOf(e); FormulaNode res = new FormulaNode(LogicOperator.OR, promised, state.ValueOf(e[0][0])); res = new FormulaNode(LogicOperator.OR, res, frag); terms.Add(res); } return(JoinTerms(LogicOperator.AND, terms)); }
private FormulaNode GenLC1(FormulaNode stateSet, SymbolicState state) { List <FormulaNode> terms = new List <FormulaNode>(); foreach (var e in elementary) { if (e.GetLogicOperator() != LogicOperator.EX) { continue; } string nextName = "succ" + uniqueId.GetTicket().ToString(); SymbolicState next = new SymbolicState(elementary, nextName); FormulaNode existsInState = state.ValueOf(e); FormulaNode notExistsInState = new FormulaNode(LogicOperator.NOT, existsInState, null); FormulaNode nextValid = SymbolicState.Substitute(stateSet, state, next); FormulaNode transition = GenTransition(state, next); FormulaNode body = e[0]; FormulaNode occursNext = next.ValueOf(body); FormulaNode hasSucc = new FormulaNode(LogicOperator.AND, nextValid, transition); hasSucc = new FormulaNode(LogicOperator.AND, hasSucc, occursNext); hasSucc = next.Quantify(LogicOperator.EXISTS, hasSucc); terms.Add(new FormulaNode(LogicOperator.OR, notExistsInState, hasSucc)); } return(JoinTerms(LogicOperator.AND, terms)); }
/* Generates a formula representing the fact that for <state> either * the eventuality is not promised or that if it is, then there * exists a fragment of <stateSet> rooted at <state> that has * a frontier node who satisfied the eventuallity */ private FormulaNode GenE(FormulaNode stateSet, SymbolicState state) { ComputeEUFragments(stateSet, state); List <FormulaNode> terms = new List <FormulaNode>(); foreach (var e in elementary) { if (e.GetLogicOperator() != LogicOperator.EX) { continue; } if (e[0].GetLogicOperator() != LogicOperator.EU) { continue; } FormulaNode notPromised = new FormulaNode(LogicOperator.NOT); notPromised.SetChildren(state.ValueOf(e), null); FormulaNode res = new FormulaNode(LogicOperator.OR); res.SetChildren(notPromised, new FormulaNode(LogicOperator.NOT)); res[1].SetChildren(state.ValueOf(e[0][0]), null); FormulaNode frag = fragEU[e[0]]; res = new FormulaNode(LogicOperator.OR, res, frag); terms.Add(res); } return(JoinTerms(LogicOperator.AND, terms)); }
/* Check if we reached a fixpoint. That is, if there are no states in <largeSet> * which are absent from <smallSet>. */ private bool IsFixpoint(FormulaNode largeSet, FormulaNode smallSet, SymbolicState v) { FormulaNode notNew = new FormulaNode(LogicOperator.NOT, smallSet, null); FormulaNode stateRemoved = new FormulaNode(LogicOperator.AND, largeSet, notNew); stateRemoved = v.Quantify(LogicOperator.EXISTS, stateRemoved); return(!FormulaCNF.QBFSAT(stateRemoved)); }
/* * <au> is an elementary formula of the form EX(ER(p,q)) */ private FormulaNode ComputeAUFragment(FormulaNode au, FormulaNode stateSet, SymbolicState state) { #if DEBUG Console.WriteLine("Computing fragment for " + au); #endif FormulaNode frag = FormulaParser.Parse("~TRUE"); FormulaNode notLeft = new FormulaNode(LogicOperator.NOT, au[0][0], null); FormulaNode notRight = new FormulaNode(LogicOperator.NOT, au[0][1], null); while (true) { string nextName = "succ" + uniqueId.GetTicket().ToString(); SymbolicState next = new SymbolicState(elementary, nextName); FormulaNode transition = GenTransition(state, next); FormulaNode memberOf = SymbolicState.Substitute(stateSet, state, next); FormulaNode nextFrag = SymbolicState.Substitute(frag, state, next); FormulaNode newFrag = new FormulaNode(LogicOperator.AND, transition, memberOf); newFrag = new FormulaNode(LogicOperator.AND, newFrag, nextFrag); newFrag = next.Quantify(LogicOperator.EXISTS, newFrag); newFrag = new FormulaNode(LogicOperator.AND, state.ValueOf(notLeft.NNF()), newFrag); // Add the big conjunction needed for fragAU List <FormulaNode> fragTerms = new List <FormulaNode>(); foreach (FormulaNode el in elementary) { if (el.GetLogicOperator() != LogicOperator.EX) { continue; } nextName = "succ" + uniqueId.GetTicket().ToString(); next = new SymbolicState(elementary, nextName); transition = GenTransition(state, next); memberOf = SymbolicState.Substitute(stateSet, state, next); nextFrag = SymbolicState.Substitute(frag, state, next); FormulaNode lhs = state.ValueOf(el); FormulaNode rhs = new FormulaNode(LogicOperator.AND, transition, memberOf); rhs = new FormulaNode(LogicOperator.AND, rhs, nextFrag); rhs = new FormulaNode(LogicOperator.AND, rhs, next.ValueOf(SymbolicState.Substitute(el[0], state, next))); rhs = next.Quantify(LogicOperator.EXISTS, rhs); fragTerms.Add(new FormulaNode(LogicOperator.IMP, lhs, rhs)); } newFrag = new FormulaNode(LogicOperator.AND, newFrag, JoinTerms(LogicOperator.AND, fragTerms)); newFrag = new FormulaNode(LogicOperator.OR, state.ValueOf(notRight.NNF()), newFrag); if (IsFixpoint(newFrag, frag, state)) { return(frag); } frag = newFrag; } }
/* Generates a formula representing the fact that <state> has a * successor in <stateSet>. Does not guarantee that <state> itself * belongs to the set. */ private FormulaNode GenSucc(FormulaNode stateSet, SymbolicState state) { string nextName = "succ" + uniqueId.GetTicket().ToString(); SymbolicState next = new SymbolicState(elementary, nextName); FormulaNode transition = GenTransition(state, next); FormulaNode memberOf = SymbolicState.Substitute(stateSet, state, next); FormulaNode result = new FormulaNode(LogicOperator.AND, transition, memberOf); result = next.Quantify(LogicOperator.EXISTS, result); return(result); }
/* Replace the variables describing the state <from> with the ones that describe * state <to> */ public static FormulaNode Substitute(FormulaNode formula, SymbolicState from, SymbolicState to) { if (formula.GetLogicOperator() == LogicOperator.VAR) { if (from.nameToElementary.Keys.Contains(formula.GetName())) { // this variable represents an elementary formula var elementary = from.nameToElementary[formula.GetName()]; return(new FormulaNode(to.elementaryNames[elementary])); } else { return(new FormulaNode(formula.GetName())); } } if (formula.GetLogicOperator() == LogicOperator.ALL || formula.GetLogicOperator() == LogicOperator.EXISTS) { FormulaNode result = new FormulaNode(formula.GetLogicOperator()); if (from.nameToElementary.Keys.Contains(formula.GetName())) { // this variable represents an elementary formula var elementary = from.nameToElementary[formula.GetName()]; result.SetName(to.elementaryNames[elementary]); } else { result.SetName(formula.GetName()); } result.SetChildren(Substitute(formula[0], from, to), null); return(result); } FormulaNode res = new FormulaNode(formula.GetLogicOperator()); FormulaNode left = Substitute(formula[0], from, to); FormulaNode right = null; if (formula[1] != null) { right = Substitute(formula[1], from, to); } res.SetChildren(left, right); return(res); }
private void ComputeEUFragments(FormulaNode stateSet, SymbolicState state) { #if DEBUG Console.WriteLine("Compute fragments"); #endif foreach (var e in elementary) { if (e.GetLogicOperator() != LogicOperator.EX) { continue; } if (e[0].GetLogicOperator() != LogicOperator.EU) { continue; } #if DEBUG Console.WriteLine("Computing fragment for " + e); #endif FormulaNode frag = FormulaParser.Parse("~TRUE"); while (true) { string nextName = "succ" + uniqueId.GetTicket().ToString(); SymbolicState next = new SymbolicState(elementary, nextName); FormulaNode transition = GenTransition(state, next); FormulaNode memberOf = SymbolicState.Substitute(stateSet, state, next); FormulaNode nextFrag = SymbolicState.Substitute(frag, state, next); FormulaNode newFrag = new FormulaNode(LogicOperator.AND, transition, memberOf); newFrag = new FormulaNode(LogicOperator.AND, newFrag, nextFrag); newFrag = next.Quantify(LogicOperator.EXISTS, newFrag); newFrag = new FormulaNode(LogicOperator.AND, state.ValueOf(e[0][0]), newFrag); newFrag = new FormulaNode(LogicOperator.OR, state.ValueOf(e[0][1]), newFrag); if (IsFixpoint(newFrag, frag, state)) { break; } frag = newFrag; } fragEU[e[0]] = frag; } }
/* 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)); }
public bool Check() { SymbolicState v = new SymbolicState(elementary, "v"); // initially, all possible states belong to the structure FormulaNode states = new FormulaNode(FormulaNode.TRUE_LITERAL); FormulaNode oldStates; while (true) { iterations++; #if DEBUG Console.WriteLine("Iteration " + iterations.ToString()); #endif oldStates = states; FormulaNode succ = GenSucc(states, v); FormulaNode lc1 = GenLC1(states, v); FormulaNode e = GenE(states, v); FormulaNode a = GenA(states, v); states = new FormulaNode(LogicOperator.AND, states, succ); states = new FormulaNode(LogicOperator.AND, states, lc1); states = new FormulaNode(LogicOperator.AND, states, e); states = new FormulaNode(LogicOperator.AND, states, a); if (IsFixpoint(oldStates, states, v)) { break; } } #if DEBUG Console.WriteLine("Reached fixpoint. Checking for satisfying state"); #endif FormulaNode formulaValue = v.ValueOf(normalized); FormulaNode formulaAndValid = new FormulaNode(LogicOperator.AND, states, formulaValue); FormulaNode sat = v.Quantify(LogicOperator.EXISTS, formulaAndValid); return(FormulaCNF.QBFSAT(sat)); }