// Trnasfer the node to PNF (the formula is assumed to be in NNF) // We assume that the formula also has no temporal operators public FormulaNode PNF() { if (this.logicOp == LogicOperator.VAR) { return(new FormulaNode(this.name)); } FormulaNode res = null, left = null, right = null; ISet <string> leftSet, rightSet; string varname; if (this.logicOp == LogicOperator.NOT) { res = new FormulaNode(LogicOperator.NOT); res.SetChildren(new FormulaNode(this.childNodes[0].name), null); return(res); } if (this.logicOp == LogicOperator.EXISTS || this.logicOp == LogicOperator.ALL) { res = new FormulaNode(this.logicOp, this.name); res.SetChildren(this.childNodes[0].PNF(), null); return(res); } // Since we assume NNF, all NOT nodes are next to variables // Thus all of the remaining operators are binary left = this.childNodes[0].PNF(); right = this.childNodes[1].PNF(); leftSet = left.GetVariables(); rightSet = right.GetVariables(); if (this.logicOp == LogicOperator.AND || this.logicOp == LogicOperator.OR) { FormulaNode temp; if (left.logicOp == LogicOperator.EXISTS || left.logicOp == LogicOperator.ALL) { if (rightSet.Contains(left.name)) { varname = UniquePNFVariable(); left = left.Substitute(left.name, varname); } res = new FormulaNode(left.logicOp, left.name); temp = new FormulaNode(this.logicOp); temp.SetChildren(left.childNodes[0], right); res.SetChildren(temp.PNF(), null); } else if (right.logicOp == LogicOperator.EXISTS || right.logicOp == LogicOperator.ALL) { if (leftSet.Contains(right.name)) { varname = UniquePNFVariable(); right = right.Substitute(right.name, varname); } res = new FormulaNode(right.logicOp, right.name); temp = new FormulaNode(this.logicOp); temp.SetChildren(left, right.childNodes[0]); res.SetChildren(temp.PNF(), null); } else { res = new FormulaNode(this.logicOp); res.SetChildren(left, right); } } // For convenience, we get rid of "->" operators if (this.logicOp == LogicOperator.IMP) { res = new FormulaNode(LogicOperator.OR); res.SetChildren(new FormulaNode(LogicOperator.NOT), right); res.childNodes[0].SetChildren(left, null); res = res.NNF().PNF(); } return(res); }