// 2nd step public static Step EliminateImpliesStep(Step step) { List <Symbol> symbols = step.Top.ReverseBFS(); step.Title = "Eliminating Implies"; foreach (Symbol symbol in symbols) { if (symbol is Operator && symbol.Name == "IMPLIES") { var parentSymbol = symbol.Parent; var leftChildSymbol = symbol.Children[0]; var rightChildSymbol = symbol.Children[1]; Symbol newSymbolOperator = new Operator(name: "OR"); Symbol newChildLeft = new Negation(); // 1st copy left child of IMPLIES statement newChildLeft.SetChild(0, leftChildSymbol.Clone()); // 2nd asign Negation before copied left child of IMPLIES newSymbolOperator.SetChild(0, newChildLeft); // We can only clone because right child if free of change newSymbolOperator.SetChild(1, rightChildSymbol.Clone()); if (parentSymbol == null) { step.Top = newSymbolOperator; } else { parentSymbol.SetChild(symbol.IndexInParent, newSymbolOperator); } } } return(step); }
// 3rd step public static Step MoveNegationInwardsStep(Step step) { step.Title = "Moving Negation Inwards"; bool endConditional; do { endConditional = false; List <Symbol> symbols = step.Top.ReverseBFS(); foreach (var symbol in symbols) { if (symbol is Negation && symbol.Children[0].IsFinal == false) { var parentSymbol = symbol.Parent; var childSymbol = symbol.Children[0]; if (childSymbol is Negation) // Negation case { endConditional = true; if (parentSymbol == null) { step.Top = childSymbol.Children[0]; } else { parentSymbol.SetChild(symbol.IndexInParent, childSymbol.Children[0]); } } else if (childSymbol is Operator) // AND and OR case { // setting end conditional to true endConditional = true; if (childSymbol.Name == "AND") { Symbol newOperatorSymbol = new Operator(name: "OR"); var leftChildSymbol = childSymbol.Children[0]; var rightChildSymbol = childSymbol.Children[1]; Symbol newLeftChild = new Negation(); Symbol newRightChild = new Negation(); newLeftChild.SetChild(0, leftChildSymbol.Clone()); newRightChild.SetChild(1, rightChildSymbol.Clone()); newOperatorSymbol.SetChild(0, newLeftChild); newOperatorSymbol.SetChild(1, newRightChild); if (parentSymbol == null) { step.Top = newOperatorSymbol; } else { parentSymbol.SetChild(symbol.IndexInParent, newOperatorSymbol); } } else if (childSymbol.Name == "OR") { Symbol newOperatorSymbol = new Operator(name: "AND"); var leftChildSymbol = childSymbol.Children[0]; var rightChildSymbol = childSymbol.Children[1]; Symbol newLeftChild = new Negation(); Symbol newRightChild = new Negation(); newLeftChild.SetChild(0, leftChildSymbol.Clone()); newRightChild.SetChild(1, rightChildSymbol.Clone()); newOperatorSymbol.SetChild(0, newLeftChild); newOperatorSymbol.SetChild(1, newRightChild); if (parentSymbol == null) { step.Top = newOperatorSymbol; } else { parentSymbol.SetChild(symbol.IndexInParent, newOperatorSymbol); } } } else if (childSymbol is Quantifier) // FORALL and EXISTS case { // setting end conditional to true endConditional = true; if (childSymbol.Name == "FORALL") { Symbol newOperatorSymbol = new Operator(name: "EXISTS"); var leftChildSymbol = childSymbol.Children[0]; var rightChildSymbol = childSymbol.Children[1]; Symbol newRightChild = new Negation(); newRightChild.SetChild(0, rightChildSymbol.Clone()); newOperatorSymbol.SetChild(0, leftChildSymbol); newOperatorSymbol.SetChild(1, newRightChild); if (parentSymbol == null) { step.Top = newOperatorSymbol; } else { parentSymbol.SetChild(symbol.IndexInParent, newOperatorSymbol); } } else if (childSymbol.Name == "EXISTS") { Symbol newOperatorSymbol = new Operator(name: "FORALL"); var leftChildSymbol = childSymbol.Children[0]; var rightChildSymbol = childSymbol.Children[1]; Symbol newRightChild = new Negation(); newRightChild.SetChild(0, rightChildSymbol.Clone()); newOperatorSymbol.SetChild(0, leftChildSymbol); newOperatorSymbol.SetChild(1, newRightChild); if (parentSymbol == null) { step.Top = newOperatorSymbol; } else { parentSymbol.SetChild(symbol.IndexInParent, newOperatorSymbol); } } } } } } while (endConditional); return(step); }