private Block RelatedTheorems() { string firstContent = FirstBlock.GetContent(true).ToString(), secondContent = SecondBlock.GetContent(true).ToString(); bool isConjunctive = Logic.IsConjunction; if (firstContent == secondContent) { return(FirstBlock.IsNegated != SecondBlock.IsNegated ? new Block(isConjunctive ? "false" : "true") : // complement FirstBlock); // idempotent } switch (firstContent) { case "true": return(isConjunctive ? SecondBlock : new Block("true")); // identity case "false": return(isConjunctive ? new Block("false") : SecondBlock); // annulment } return(secondContent switch { "true" => isConjunctive ? FirstBlock : new Block("true"), // identity "false" => isConjunctive ? new Block("false") : SecondBlock, // annulment _ => ConcatStoredBlocks(), });
/// <summary> /// a<=>b into (a=>b)&(b=>a) into ((~a||b)&(a||~b)) (Prioritize CNF over DNF) /// Warning: This method is one directional, do not use this to convert a logic block into <=> /// </summary> /// <param name="logicBlock"></param> /// <returns>The block passed to this method</returns> public override Block Translate() { if (FirstBlock == null || SecondBlock == null) { ThrowErrorOnFirstCheck(); } if (!Logic.IsBiconditional) { return(ConcatStoredBlocks()); } Block cloneFirstBlock = new Block(FirstBlock.GetContent(true).ToString(), FirstBlock.IsNegated), cloneSecondBlock = new Block(SecondBlock.GetContent(true).ToString(), SecondBlock.IsNegated); // (~a||b) FirstBlock.SetNegation(!FirstBlock.IsNegated) .InsertBack(new Block(PropositionalLogic.Disjunction)) .InsertBack(SecondBlock); // (a||~b) cloneFirstBlock .InsertBack(new Block(PropositionalLogic.Disjunction)) .InsertBack(cloneSecondBlock.SetNegation(!cloneFirstBlock.IsNegated)); // ((~a||b)&(a||~b)) var nested = new Block(FirstBlock); nested.InsertBack(new Block(PropositionalLogic.Conjunction)) .InsertBack(new Block(cloneFirstBlock)); return(nested); }
/// <summary> /// Only a||(b&c) <=> (a||b)&(a||c) is available to prioritize CNF over DNF /// </summary> /// <param name="logicBlock"></param> /// <returns>A block containing nested contents, which are distributed from original one</returns> public override Block Translate() { if (FirstBlock == null || Logic == null || SecondBlock == null) { ThrowErrorOnFirstCheck(); } bool isFirstNormal = FirstBlock.ContentType == ContentType.Normal, isSecondNormal = SecondBlock.ContentType == ContentType.Normal; // from left to right instead of expanding from the least to the most symbols // no point in taking a&b or similars into consideration if (!isFirstNormal || !isSecondNormal) { var logic = Logic.ToString(); // swap places: (a&b)||c into c||(a&b) locally if (isSecondNormal) { (FirstBlock, SecondBlock) = (SecondBlock, FirstBlock); } // a&(b||c) like if (FirstBlock.ContentType == ContentType.Normal) { return(Distribute( FirstBlock.IsNegated, FirstBlock.GetContent(true).ToString(), SecondBlock.GetContent() as Block)); } // (a||b)&(c||d) like if (FirstBlock.ContentType == ContentType.Nested) { BlockIterator.ForEach(FirstBlock.GetContent() as Block, (currentBlock) => { if (currentBlock.ContentType == ContentType.Normal) { Distribute( currentBlock.IsNegated, currentBlock.GetContent(true).ToString(), SecondBlock.GetContent() as Block ); } }); return(FirstBlock.GetContent() as Block); } } return(ConcatStoredBlocks()); }